Flutter CupertinoTabBar: невозможно переключиться на вкладку по индексу для события потока - PullRequest
0 голосов
/ 05 марта 2019

Попытка активировать CupertinoTabBar's вкладку 0, когда вкладка 1 активна на 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, а это не то, что нам нужно.

С чем это связано, как мы можем переключиться на вкладку внешнего события?

1 Ответ

1 голос
/ 14 марта 2019

Это решается с помощью StreamBuilder, метод, который был на самом деле попытался первым. Этот метод имеет другое предостережение: он переключается на вкладку 0, когда нам нужно остаться, например, на 1-й вкладке, и это происходит, когда мы возвращаемся с другого экрана, открытого в верхней части экрана с вкладками.

Что не так в этот раз? Построитель потока повторно генерирует последнее событие (поток на основе 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();
                  }
                },
              );
            },
          ),
        );
      }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...