再学习过程中在本例子中用到了几个注意点进行笔记:
实现效果:
先在类中定义实例变量
当需要发生变化的时候调用setState方法即可
当调用setState方法的时候,flutter会重新运行对应State组件中的build方法
代码实现
// 有状态组件Calculator的定义
// 1. 定义一个继承StatefulWidget的组件
class Calculator extends StatefulWidget {
final num initX, initY;
Calculator({Key key, @required this.initX, @required this.initY})
: super(key: key);
// 2. 重写其中的createState方法
// 返回一个该组件的State组件
// 该函数返回_CalculatorState的类
@override
_CalculatorState createState() =>
_CalculatorState(initX: initX, initY: initY);
}
// 该组件继承State,且其泛型设为对应的statefulWidget类型
// 下面写对应的功能函数即可
class _CalculatorState extends State {
// 参数的初始化
num initX = 0, initY = 0, result;
String _operator = "+";
bool setY = false;
static final suppoerOperator = ['+', '-', '*', '/'];
// 对应的构造函数
_CalculatorState({Key key});
void calRes() {
// 需要重新设置参数的时候
// 通过setState设置对应参数值
setState(() {
switch (_operator) {
case "+":
result = initX + initY;
break;
case "-":
result = initX - initY;
break;
case "*":
result = initX * initY;
break;
case "/":
result = initX / initY;
break;
default:
}
});
// 下面的功能代码先省略
}
// 前面代码省略,定义了头部的计算模块
// 因为这个组件除了
class EqualInput extends StatelessWidget {
// 这些参数需要通过父组件传入
final num initX, initY, result;
final String op;
// 这里采用具名构造函数的声明方法
const EqualInput(
{Key key,
@required this.initY,
@required this.initX,
@required this.result,
@required this.op})
: super(key: key);
@override
Widget build(BuildContext context) {
return Container(
child: Row(
children: [
Expanded(
child: Container(
child: Text(
'$initX',
textAlign: TextAlign.center,
style: TextStyle(color: Colors.red[200], fontSize: 16.0),
),
decoration: BoxDecoration(
border: Border.all(width: 1, color: Colors.red),
borderRadius: BorderRadius.all(Radius.circular(10))),
padding: EdgeInsets.all(10),
margin: EdgeInsets.all(10),
),
flex: 2),
Expanded(
child: Container(
child: Text(
'$op',
textAlign: TextAlign.center,
style: TextStyle(color: Colors.red[200], fontSize: 16.0),
),
decoration: BoxDecoration(
border: Border.all(width: 1, color: Colors.red),
borderRadius: BorderRadius.all(Radius.circular(10))),
padding: EdgeInsets.all(10),
margin: EdgeInsets.all(10),
),
flex: 1),
Expanded(
child: Container(
child: Text(
'$initY',
textAlign: TextAlign.center,
style: TextStyle(color: Colors.red[200], fontSize: 16.0),
),
decoration: BoxDecoration(
border: Border.all(width: 1, color: Colors.red),
borderRadius: BorderRadius.all(Radius.circular(10))),
padding: EdgeInsets.all(10),
margin: EdgeInsets.all(10),
),
flex: 2),
Text(
'=',
style: TextStyle(color: Colors.red[200], fontSize: 16.0),
),
Expanded(
child: Container(
child: Text(
'$result',
textAlign: TextAlign.center,
style: TextStyle(color: Colors.red[200], fontSize: 16.0),
),
decoration: BoxDecoration(
border: Border.all(width: 1, color: Colors.red),
borderRadius: BorderRadius.all(Radius.circular(10))),
padding: EdgeInsets.all(10),
margin: EdgeInsets.all(10),
),
flex: 2),
],
),
);
}
}
class _CalculatorState extends State {
// ......省略了上面部分代码,只留下相关重要的代码
Function getData(num value) {
return () {
setState(() {
!setY
? initX = int.parse(initX.toString() + value.toString())
: initY = int.parse(initY.toString() + value.toString());
});
};
}
@override
Widget build(BuildContext context) {
return Center(
child: Container(
child: Column(
children: [
// 省略上面的组件,只看KeyBoard组件
KeyBoard(onChange: getData),
],
crossAxisAlignment: CrossAxisAlignment.center,
),
));
}
}
class KeyBoard extends StatelessWidget {
final Function onChange;
const KeyBoard({Key key, @required this.onChange}) : super(key: key);
@override
Widget build(BuildContext context) {
final List numberKey = List.generate(9, (i) => i + 1)
.map((item) => RaisedButton(
// 这里通过在父元素的回调中传回item
// 父元素就可以接下来通过回传的item参数作出相应的操作
onPressed: onChange(item),
child: Center(
child: Text(
'$item',
style: TextStyle(fontSize: 64, color: Colors.white),
textAlign: TextAlign.center,
),
),
color: Colors.green[200],
))
.toList();
return Flexible(
child: Container(
child: GridView(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
crossAxisSpacing: 5.0,
mainAxisSpacing: 10.0,
childAspectRatio: 1),
children: numberKey),
margin: EdgeInsets.all(10),
),
flex: 1,
);
}
}
final List numberKey = List.generate(9, (i) => i + 1)
.map((item) => RaisedButton(
onPressed: onChange(item),
child: Center(
child: Text(
'$item',
style: TextStyle(fontSize: 64, color: Colors.white),
textAlign: TextAlign.center,
),
),
color: Colors.green[200],
))
.toList();
一般函数的定义方法,因为函数返回值也是对象,所以直接定义函数返回值的类型作为函数类型即可
如果函数的返回值还是函数,可以通过下面的方法解决, 因为返回的是一个没有参数的函数,Function即可,通过闭包的方式实现后续功能
class _CalculatorState extends State {
// ......省略了上面部分代码,只留下相关重要的代码
// 返回值类型为function
Function getData(num value) {
return () {
setState(() {
!setY
? initX = int.parse(initX.toString() + value.toString())
: initY = int.parse(initY.toString() + value.toString());
});
};
}
@override
Widget build(BuildContext context) {
return Center(
child: Container(
child: Column(
children: [
// 省略上面的组件,只看KeyBoard组件
KeyBoard(onChange: getData),
],
crossAxisAlignment: CrossAxisAlignment.center,
),
));
}
}
class KeyBoard extends StatelessWidget {
final Function onChange;
const KeyBoard({Key key, @required this.onChange}) : super(key: key);
}
import "package:flutter/material.dart";
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
child: MaterialApp(
title: '计算器',
theme: ThemeData(primaryColor: Colors.red),
home: Scaffold(
appBar: AppBar(
title: Text('计算器'),
),
body: Calculator(initX: 0, initY: 0)),
));
}
}
class Calculator extends StatefulWidget {
final num initX, initY;
Calculator({Key key, @required this.initX, @required this.initY})
: super(key: key);
@override
_CalculatorState createState() => _CalculatorState(initX: initX, initY: initY);
}
class _CalculatorState extends State {
num initX, initY, result;
String _operator = "+";
bool setY = false;
static final suppoerOperator = ['+', '-', '*', '/'];
_CalculatorState({Key key, @required this.initX, @required this.initY});
Function getData(num value) {
return () {
setState(() {
!setY
? initX = int.parse(initX.toString() + value.toString())
: initY = int.parse(initY.toString() + value.toString());
});
};
}
void calRes() {
setState(() {
switch (_operator) {
case "+":
result = initX + initY;
break;
case "-":
result = initX - initY;
break;
case "*":
result = initX * initY;
break;
case "/":
result = initX / initY;
break;
default:
}
});
}
Function handleOperator(String _op) {
return () {
if (suppoerOperator.contains(_op) && !setY) {
setState(() {
_operator = _op;
setY = true;
});
}
if (_op == '=') {
calRes();
setState(() {
setY = false;
});
}
};
}
@override
Widget build(BuildContext context) {
List operatorList = ['+', '-', '*', '/', '=']
.map(
(item) => Flexible(
child: Container(
child: RaisedButton(
onPressed: handleOperator(item),
child: Text(
'$item',
style: TextStyle(color: Colors.red, fontSize: 12),
textAlign: TextAlign.center,
),
color: Colors.greenAccent,
),
margin: EdgeInsets.fromLTRB(
suppoerOperator.indexOf(item) == 0 ? 0 : 10, 0, 0, 0),
),
flex: 1),
)
.toList();
return Center(
child: Container(
child: Column(
children: [
EqualInput(initY: initY, initX: initX, result: result, op: _operator),
Container(
height: 30,
child: Row(
children: operatorList,
crossAxisAlignment: CrossAxisAlignment.center,
),
margin: EdgeInsets.all(10),
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Container(
child: RaisedButton(
child: Text(
'清空',
style: TextStyle(color: Colors.white),
),
onPressed: () {
setState(() {
initY = 0;
initX = 0;
result = 0;
_operator = '+';
setY = false;
});
},
color: Colors.green,
),
margin: EdgeInsets.only(right: 10),
)
],
),
KeyBoard(onChange: getData),
],
crossAxisAlignment: CrossAxisAlignment.center,
),
));
}
}
class KeyBoard extends StatelessWidget {
final Function onChange;
const KeyBoard({Key key, @required this.onChange}) : super(key: key);
@override
Widget build(BuildContext context) {
final List numberKey = List.generate(9, (i) => i + 1)
.map((item) => RaisedButton(
onPressed: onChange(item),
child: Center(
child: Text(
'$item',
style: TextStyle(fontSize: 64, color: Colors.white),
textAlign: TextAlign.center,
),
),
color: Colors.green[200],
))
.toList();
return Flexible(
child: Container(
child: GridView(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
crossAxisSpacing: 5.0,
mainAxisSpacing: 10.0,
childAspectRatio: 1),
children: numberKey),
margin: EdgeInsets.all(10),
),
flex: 1,
);
}
}
class EqualInput extends StatelessWidget {
final num initX, initY, result;
final String op;
const EqualInput(
{Key key,
@required this.initY,
@required this.initX,
@required this.result,
@required this.op})
: super(key: key);
@override
Widget build(BuildContext context) {
return Container(
child: Row(
children: [
Expanded(
child: Container(
child: Text(
'$initX',
textAlign: TextAlign.center,
style: TextStyle(color: Colors.red[200], fontSize: 16.0),
),
decoration: BoxDecoration(
border: Border.all(width: 1, color: Colors.red),
borderRadius: BorderRadius.all(Radius.circular(10))),
padding: EdgeInsets.all(10),
margin: EdgeInsets.all(10),
),
flex: 2),
Expanded(
child: Container(
child: Text(
'$op',
textAlign: TextAlign.center,
style: TextStyle(color: Colors.red[200], fontSize: 16.0),
),
decoration: BoxDecoration(
border: Border.all(width: 1, color: Colors.red),
borderRadius: BorderRadius.all(Radius.circular(10))),
padding: EdgeInsets.all(10),
margin: EdgeInsets.all(10),
),
flex: 1),
Expanded(
child: Container(
child: Text(
'$initY',
textAlign: TextAlign.center,
style: TextStyle(color: Colors.red[200], fontSize: 16.0),
),
decoration: BoxDecoration(
border: Border.all(width: 1, color: Colors.red),
borderRadius: BorderRadius.all(Radius.circular(10))),
padding: EdgeInsets.all(10),
margin: EdgeInsets.all(10),
),
flex: 2),
Text(
'=',
style: TextStyle(color: Colors.red[200], fontSize: 16.0),
),
Expanded(
child: Container(
child: Text(
'$result',
textAlign: TextAlign.center,
style: TextStyle(color: Colors.red[200], fontSize: 16.0),
),
decoration: BoxDecoration(
border: Border.all(width: 1, color: Colors.red),
borderRadius: BorderRadius.all(Radius.circular(10))),
padding: EdgeInsets.all(10),
margin: EdgeInsets.all(10),
),
flex: 2),
],
),
);
}
}
如果你看到了这里,我想说,很感谢你花了这么多时间来看这个,辛苦你了。