1

尝试在CupertinoTabBar's选项卡 1 处于活动状态时激活选项卡 0,stream event如下所示:

{

class HomeScreen extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => HomeScreenState();
}

class HomeScreenState extends State<HomeScreen> {

  int _currentTabIndex = 0;

  @override
  void initState() {
    super.initState();
    _drawerStream.listen((state) {
      if (_currentTabIndex != 0) {
        SchedulerBinding.instance.addPostFrameCallback((_) {
          setState(() => _currentTabIndex = 0);
        });
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      drawer: Drawer(
        elevation: 0.0,
        child: DrawerScreen(),
      ),
      body: CupertinoTabScaffold(
        tabBar: CupertinoTabBar(
          onTap: (index) {
            _currentTabIndex = index;
          },
          currentIndex: _currentTabIndex,
          backgroundColor: Colors.white,
          items: <BottomNavigationBarItem>[
            BottomNavigationBarItem(
              title: Text('Main'),
              icon: Icon(IconData(0xe800), size: 20),
            ),
            BottomNavigationBarItem(
              title: Text('Goodies'),
              icon: Icon(IconData(0xe84b), size: 20),
            ),
          ],
        ),
        tabBuilder: (BuildContext context, int index) {
          return CupertinoTabView(
            builder: (BuildContext context) {
              switch (index) {
                case 0: return MainScreen();
                case 1: return GoodiesScreen();
              }
            },
          );
        },
      ),
    );
  }
}
}

当事件来自_drawerStream. 仍在使用调试器跟踪发生了什么,它发现CupertinoTabBar小部件构建了 2 次,第一次它的当前索引参数为 0,这是我们真正需要的。但是第二次运行它会在当前索引参数设置为 1 的情况下重建,这不是我们想要的。

这是什么原因,我们如何切换到外部事件的选项卡?

4

2 回答 2

1

它是使用 StreamBuilder 解决的,这是一种实际上首先尝试的方法。这种方法有一个不同的警告:当我们必须保持打开时,它会切换到选项卡 0,例如,第一个选项卡,当我们从带有选项卡的屏幕顶部打开的另一个屏幕返回时会发生这种情况。

这次怎么了?流构建器重新发出最后一个事件(BehaviourSubject基于流),这种方式_currentTabIndex设置为 0,而我们需要它来保持当前值。解决方案是“记住”最后一个事件并识别它刚刚重新发出。这可能无法解决所有类似的问题,但至少提供了一个线索。

一段代码来说明解决方案:

class HomeScreenState extends State<HomeScreen> {

  int _currentTabIndex = 0;
  AsyncSnapshot<UIState> lastSnapshot;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      drawer: Drawer(
        elevation: 0.0,
        child: DrawerScreen(),
      ),
      body: StreamBuilder(
        stream: _drawerStream,
        builder: (context, AsyncSnapshot<UIState> snapshot) {
          if (_currentTabIndex != 0 && lastSnapshot != snapshot) {
            SchedulerBinding.instance.addPostFrameCallback((_) =>
              setState(() => _currentTabIndex = nextTab));
          }
          lastSnapshot = snapshot;
          return CupertinoTabScaffold(
            tabBar: CupertinoTabBar(
              onTap: (index) {
                _currentTabIndex = index;
              },
              currentIndex: _currentTabIndex,
              backgroundColor: Colors.white,
              items: <BottomNavigationBarItem>[
                BottomNavigationBarItem(
                  title: Text('Main'),
                  icon: Icon(IconData(0xe800), size: 20),
                ),
                BottomNavigationBarItem(
                  title: Text('Goodies'),
                  icon: Icon(IconData(0xe84b), size: 20),
                ),
              ],
            ),
            tabBuilder: (BuildContext context, int index) {
              return CupertinoTabView(
                builder: (BuildContext context) {
                  switch (index) {
                    case 0: return MainScreen();
                    case 1: return GoodiesScreen();
                  }
                },
              );
            },
          ),
        );
      }
}
于 2019-03-14T08:11:34.817 回答
0

您也可以使用 GlobalKeys,您的问题应该会消失。这是有关如何执行此操作的清晰教程

https://medium.com/@info_4766/ios-tab-bar-in-flutter-9379cf09df31

于 2020-03-04T12:23:21.153 回答