我对扑扑非常陌生,在线阅读的数百万答案使我更加困惑。这是我的页面:
class SecondDegreePage extends StatefulWidget {
const SecondDegreePage({Key key}) : super(key: key);
@override
SecondDegreePageState createState() => SecondDegreePageState();
}
class SecondDegreePageState extends State<SecondDegreePage> {
final GlobalKey<FormState> _formKey = new GlobalKey();
final controllerParamA = TextEditingController();
final controllerParamB = TextEditingController();
final controllerParamC = TextEditingController();
Quadratic _solver = Quadratic([
(Random().nextInt(10) + 1) * 1.0,
(Random().nextInt(10) + 1) * 1.0,
(Random().nextInt(10) + 1) * 1.0
]);
void updateData() {
setState(() {
_solver = Quadratic([
(Random().nextInt(10) + 1) * 1.0,
(Random().nextInt(10) + 1) * 1.0,
(Random().nextInt(10) + 1) * 1.0
]);
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(AppLocalization.of(context).title),
),
body: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
// Input form
Form(
key: _formKey,
child: Padding(
padding: EdgeInsets.all(20),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
EquationInputField(
controller: controllerParamA,
textHint: 'a',
width: 70,
),
EquationInputField(
controller: controllerParamB,
textHint: 'b',
width: 70,
),
EquationInputField(
controller: controllerParamC,
textHint: 'c',
width: 70,
),
],
),
),
),
// Submit button
Padding(
padding: EdgeInsets.fromLTRB(0, 30, 0, 30),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
RaisedButton(
onPressed: () => updateData(),
color: Colors.blue,
elevation: 6,
child: Text(
AppLocalization.of(context).solve,
style: TextStyle(
color: Colors.white
),
),
)
],
),
),
//Solutions
Expanded(
child: Padding(
padding: EdgeInsets.only(bottom: 10),
child: AlgebraicSolutions(
solver: _solver
),
),
),
],
),
);
}
@override
void dispose() {
controllerParamA.dispose();
controllerParamB.dispose();
controllerParamC.dispose();
super.dispose();
}
}
Quadratic类型只是一个执行一些数学运算的类,并不重要。问题在这一行:
RaisedButton(
onPressed: () => updateData()
}
为什么什么也没发生?我已经阅读了对setState的调用,该调用称为build方法,并且重新构建了小部件。因此,我希望
child: AlgebraicSolutions(
solver: _solver
),
此处_solver
参考已更新。 AlgebraicSolutions如下:
class AlgebraicSolutions extends StatefulWidget {
final Algebraic solver;
const AlgebraicSolutions({Key key, @required this.solver}) : super(key: key);
@override
AlgebraicSolutionsState createState() => AlgebraicSolutionsState();
}
class AlgebraicSolutionsState extends State<AlgebraicSolutions> {
//'Quadratic' is a subtype of Algebraic
Algebraic _solver;
@override
void initState() {
_solver = widget.solver;
super.initState();
}
@override
Widget build(BuildContext context) {
var solutions = _solver.solve();
return ListView.builder(
itemCount: solutions.length,
itemBuilder: (context, index) {
//...
}
);
}
}
那是因为我在AlgebraicSolutionsState中使用initState
会破坏某些东西吗?
请注意,二次型是代数类型的子类。
答案 0 :(得分:3)
是的,将初始值保存在initState
中会给您带来麻烦。该生命周期方法仅在首次构建时被调用,但是由于窗口小部件调和为兼容类型,因此使用相同的状态。即属性发生变化(小部件实例不同),但状态是同一对象。 build
被再次呼叫,但initState
没有被呼叫。
在这种情况下,我会使用吸气剂为您提供相同的便利,但始终使用当前_solver
中的widget
。然后,您可以报废initState
。
Algebraic get _solver => widget.solver;
另一个选择是didUpdateWidget
,但实际上对于其他非常简单的事情来说,这里并没有必要。