Это решается с помощью 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();
}
},
);
},
),
);
}
}