Flutter中setState触发后UI未更新:Navigator传参计数器无法递减
问题原因分析
你遇到的UI不更新问题,核心原因是**count是build方法内部的局部变量**:
- 每次调用
setState时,Flutter会重新执行build方法 - 而在
build里,你又会从ModalRoute的arguments重新读取并赋值给count,这就把之前通过setState修改的数值完全覆盖了,导致UI显示的始终是初始值
解决方案
把count和title提升为_MyHomePageState类的成员变量,只在合适的时机(比如didChangeDependencies)初始化一次,这样后续setState修改的是类的成员变量,build时就能读取到最新的数值。
修改后的代码如下:
class _MyHomePageState extends State<MyHomePage> { // 把count和title定义为State类的成员变量 int count; String title; @override void didChangeDependencies() { super.didChangeDependencies(); // 在这里初始化变量,因为didChangeDependencies会在build前调用,且能安全获取ModalRoute final routeArgs = ModalRoute.of(context)?.settings.arguments as Map<String, String>?; if(routeArgs == null){ count = 1; title = 'Title'; } else { count = int.parse(routeArgs['count']!); title = routeArgs['title']!; } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( centerTitle: true, title: Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: <Widget>[ IconButton( icon: Icon(Icons.arrow_back_ios), onPressed: (){ setState(() { count -= 1; // 现在修改的是成员变量,setState后build会读取最新值 }); }, ), InkWell( child: Container( child: Text(title), ), onTap: ()=>Navigator.of(context).pushNamed('/choice'), ), Container( child: Text(count.toString()), // 现在会显示更新后的count ), IconButton( icon: Icon(Icons.arrow_forward_ios), onPressed: () {}, ), ], ), ), drawer: Drawer(), ); } }
额外说明
- 为什么用
didChangeDependencies而不是initState?因为在initState调用时,ModalRoute.of(context)可能还未完成初始化,会返回null,而didChangeDependencies会在widget依赖的InheritedWidget(这里是ModalRoute)变化时调用,第一次build前也会执行,能确保正确获取到arguments。 - 代码里用了
?和!是空安全处理,避免潜在的空指针异常,这也是Dart空安全规范的要求。
内容的提问来源于stack exchange,提问作者Kedar Karki
相关产品推荐
相关产品推荐

