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

Flutter中CupertinoTabBar代码运行正常但组件无法重建如何解决

问题原因

你遇到的不更新问题来自两个核心错误:

  • 多处独立创建Model实例:你在LoginScreen、TabBarScreen里都单独新建了Model对象,和main.dart中MultiProvider全局维护的Model实例不是同一个对象,虽然currentStep是静态属性值会同步,但后续还有缓存问题导致视图不刷新
  • CupertinoTabView默认缓存:CupertinoTabScaffold的tabBuilder会默认缓存对应索引的CupertinoTabView,同一个索引的TabView只会执行一次build逻辑,即使外层Consumer收到更新通知,也不会触发TabView内容重建
修复步骤
  1. 删掉所有自定义创建的Model实例,全部使用Provider全局提供的实例
  2. 给动态切换的CupertinoTabView添加唯一key,触发状态变更时的强制重建
  3. 移除冗余的setState调用,Provider的notifyListeners已经可以触发Consumer重建

具体修改代码

1. 修改login.dart

class LoginScreen extends StatelessWidget {
  // 删掉自定义创建Model的代码:final model = Model();

  @override
  Widget build(BuildContext context) {
    return CupertinoPageScaffold(
      navigationBar: CupertinoNavigationBar(
        middle: Text('app',),
      ),
      child: Container(
        alignment: FractionalOffset.center,
        child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              ElevatedButton(
                child: Text('next'),
                onPressed: (){
                  // 改用Provider提供的全局实例修改状态
                  Provider.of<Model>(context, listen: false).setStep('step1');
                  Navigator.pushNamed(context, '/tab_bar');
                },
                style: ElevatedButton.styleFrom(
                    primary: CupertinoColors.white,
                    side: BorderSide(color: Colors.blue, width: 2.0)
                ),
              ),
            ]
        ),
      ),
    );
  }
}

2. 修改tab_bar.dart

class TabBarScreenState extends State<TabBarScreen> {
  // 删掉自定义创建Model的代码:final model = Model();

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    // 删掉冗余打印:print(model.getStep);
    return Consumer<Model>(
      builder: (context, model, _) => CupertinoTabScaffold(
        tabBar: CupertinoTabBar(
          backgroundColor: CupertinoColors.white,
          inactiveColor: Colors.blue,
          activeColor: Colors.blueAccent,
          border: const Border(
            top: BorderSide(
              color: CupertinoColors.activeBlue,
              width: 2.0,
            ),
          ),
          items: <BottomNavigationBarItem>[
            BottomNavigationBarItem(
              icon: Icon(Icons.favorite_outline_outlined),
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.more_vert_sharp),
            ),
          ],
        ),
        tabBuilder: (context, index) {
          late final CupertinoTabView returnValue;
          switch (index) {
            case 0:
              if (model.getStep == 'step1') {
                print('step1');
                returnValue = CupertinoTabView(
                  // 添加唯一key,step变化时触发TabView重建
                  key: ValueKey(model.getStep),
                  builder: (context) {
                  return CupertinoPageScaffold(
                    child: SafeArea(
                      child: GestureDetector(
                        onTap: (){  },
                        child: Column(
                          children: <Widget>[
                            Row(
                              mainAxisAlignment: MainAxisAlignment.center,
                              children: <Widget>[
                                Container(
                                  margin: const EdgeInsets.only(bottom: 15.0),
                                  child: FloatingActionButton(
                                    onPressed: () { 
                                      model.setStep('step2'); 
                                      // 删掉冗余的setState调用
                                    },
                                    tooltip: 'step2',
                                    child: Icon(Icons.add),
                                    backgroundColor: CupertinoColors.white,
                                    foregroundColor: CupertinoColors.black,
                                  ),
                                ),
                              ],
                            ),
                          ],
                        ),
                      ),
                    ),
                  );
                });
              }
              else if (model.getStep == 'step2') {
                print('step2');
                returnValue = CupertinoTabView(
                  // 同样添加唯一key
                  key: ValueKey(model.getStep),
                  builder: (context) {
                  return CupertinoPageScaffold(
                    child: SafeArea(
                      child: Column(
                        children: <Widget> [
                          Text('step2'),
                        ],
                      ),
                    ),
                  );
                });
              }
              else {
                returnValue = CupertinoTabView(builder: (context) {
                  return Container();
                });
              }
              break;
            case 1:
              returnValue = CupertinoTabView(builder: (context) {
                return CupertinoPageScaffold(
                  child: Text("Tab2"),
                );
              });
              break;
          }
          return returnValue;
        },
      ),
    );
  }
}

修改完成后点击按钮即可正常切换step1和step2的视图。

内容的提问来源于stack exchange,提问作者discodancer

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 17:57:06