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.