gpt4 book ai didi

Flutter 无法调用 setState 重建 widget

转载 作者:IT王子 更新时间:2023-10-29 07:09:17 27 4
gpt4 key购买 nike

我是 flutter 的新手,网上阅读的数百万答案让我更加困惑。这是我的页面:

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 调用构建方法的调用,并且重新构建了小部件。出于这个原因,我希望

child: AlgebraicSolutions(
solver: _solver
),

此处 _solver 引用得到更新。代数解决方案如下:

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 破坏了什么吗?

请注意二次型是代数型的子类。

最佳答案

是的,将初始值保存在 initState 中会给您带来麻烦。该生命周期方法仅在第一次构建时调用,但由于小部件与兼容类型协调,因此使用相同的状态。即属性改变(小部件实例不同)但状态是同一个对象。 build 被再次调用,但 initState 没有被调用。

在这种情况下,我会使用 getter 来为您提供同样的便利,但始终使用当前 widget 中的 _solver。然后你可以丢弃 initState

Algebraic get _solver => widget.solver;

另一个选项是 didUpdateWidget 但对于如此简单的事情,这里真的没有必要。

关于Flutter 无法调用 setState 重建 widget,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56445675/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com