I'm using Flutter Provider package for managing currentIndex state of CupertionTabBar. I'm doing this instead of using setState of StatefulWidget because I want to programmatically update current active tab from within the tab view pages.
Here's the app code:
import 'package:flutter/cupertino.dart';
import 'package:provider/provider.dart';
void main() {
runApp(const App());
}
class App extends StatelessWidget {
const App({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return CupertinoApp(
theme: const CupertinoThemeData(
brightness: Brightness.light,
),
home: ChangeNotifierProvider(
create: (context) => AppState(),
child: const TabsPage(),
),
);
}
}
class TabsPage extends StatelessWidget {
const TabsPage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Consumer<AppState>(
builder: (context, appState, child) {
return CupertinoTabScaffold(
tabBar: CupertinoTabBar(
backgroundColor: CupertinoColors.white,
currentIndex: appState.currentTabIndex,
onTap: (index) => appState.currentTabIndex = index,
items: const [
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.house),
activeIcon: Icon(CupertinoIcons.house_fill),
),
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.play_rectangle),
activeIcon: Icon(CupertinoIcons.play_rectangle_fill),
),
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.heart),
activeIcon: Icon(CupertinoIcons.heart_fill),
),
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.music_albums),
activeIcon: Icon(CupertinoIcons.music_albums_fill),
),
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.ellipsis_circle),
activeIcon: Icon(CupertinoIcons.ellipsis_circle_fill),
),
],
),
tabBuilder: (context, index) {
return const TabPage();
},
);
},
);
}
}
class TabPage extends StatelessWidget {
const TabPage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return CupertinoTabView(
builder: (context) => Consumer<AppState>(
builder: (context, appState, child) => Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Current Tab: ${appState.currentTabIndex}'),
const SizedBox(height: 8.0),
...List.generate(
5,
(index) => Padding(
padding: const EdgeInsets.all(8.0),
child: CupertinoButton.filled(
child: Text('Go to tab $index'),
onPressed: () => appState.currentTabIndex = index,
),
),
),
],
),
),
),
);
}
}
class AppState extends ChangeNotifier {
int _currentTabIndex = 0;
int get currentTabIndex => _currentTabIndex;
set currentTabIndex(int index) {
_currentTabIndex = index;
notifyListeners();
}
}
Checkout the live code with results on DartPad.
As you can see although AppState.currentTabIndex is updating and reflected in Text widget but current active BottomNavigationBarItem UI is not updating.
Your help is appreciated.