You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 09:01:45