在Flutter中使用SetState无效?可能是忽略了这个!
Posted 萧文翰
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在Flutter中使用SetState无效?可能是忽略了这个!相关的知识,希望对你有一定的参考价值。
这次是Flutter开发技术分享,解决的问题点来自本人实际的开发经历。
首先描述一下问题:在某个组件中调用setState()方法更新该组件状态,结果是无法做到更新效果,组件仍然维持原状。
下面我们用代码示例还原问题场景:
class _MyHomePageState extends State<MyHomePage>
bool isChecked = false;
showTestDialog()
showDialog(
context: context,
builder: (BuildContext context)
return SimpleDialog(title: Text("测试对话框标题"), children: <Widget>[
Row(children: <Widget>[
Checkbox(
value: this.isChecked,
onChanged: (bool val)
setState(()
this.isChecked = !this.isChecked;
);
debugPrint(this.isChecked.toString());
),
Text("测试复选框")
])
]);
,
);
@override
Widget build(BuildContext context)
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: RaisedButton(
child: Text("点击出现弹窗"),
onPressed: ()
showTestDialog();
,
)),
);
为了突出问题点,减少不必要的干扰,我简化了原有代码内容。通过阅读上述代码,我们得知整个Demo的界面有一个按钮构成,当按钮被点击时,showTestDialog()方法被执行。界面将显示一个小窗口,里面有一个复选框。
我们要实现的效果当然是用户点击复选框的时候,改变复选框的状态。因此,在复选框的onChanged()方法中改变了决定复选框状态的布尔值,并setState()。
然而真实的运行结果并非像预期那样产生效果。
究其原因,我们还需从setState()说起。
顾名思义,setState()要求其作用对象必须是一个有状态的组件。如果作用对象本身无状态,那么setState()将无法起作用。
因此,我们找到原因:SimpleDialog()中的子组件默认是无状态的。
接下来的解决办法就简单了,只需要在SimpleDialog组件外部“套”一个StatefulBuilder组件即可。参考下面的代码:
class _MyHomePageState extends State<MyHomePage>
bool isChecked = false;
showTestDialog()
showDialog(
context: context,
builder: (BuildContext context)
return StatefulBuilder(
builder:
(BuildContext context, void Function(void Function()) setState)
return SimpleDialog(title: Text("测试对话框标题"), children: <Widget>[
Row(children: <Widget>[
Checkbox(
value: this.isChecked,
onChanged: (bool val)
setState(()
this.isChecked = !this.isChecked;
);
debugPrint(this.isChecked.toString());
),
Text("测试复选框")
])
]);
,
);
,
);
@override
Widget build(BuildContext context)
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: RaisedButton(
child: Text("点击出现弹窗"),
onPressed: ()
showTestDialog();
,
)),
);
再次运行,对话框中的复选框可以正常响应。至此,问题解决。
以上是关于在Flutter中使用SetState无效?可能是忽略了这个!的主要内容,如果未能解决你的问题,请参考以下文章
在构建期间调用 setState() 或 markNeedsBuild() - Flutter
Flutter :setState() 或 markNeedsBuild() 在构建期间调用
Flutter:我可以在 BLoC 架构中使用 setState() 吗?
编辑文本控制器更新小部件值而不调用 setState() - Flutter
成员 'setState' 只能在 'package:flutter/src/widgets/framework.dart' 的子类的实例成员中使用