CupertinoTabBar 和 BottomNavigationBarItem UI 未使用 ChangeNotifierProvider 更新
我正在使用 Flutter Provider
包来管理 currentIndex CupertionTabBar 的状态。我这样做而不是使用
StatefulWidget
的 setState
,因为我想以编程方式从选项卡视图页面内更新当前活动选项卡。
以下是应用代码:
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();
}
}
在 DartPad 上查看实时代码及其结果。
正如您所看到的,尽管 AppState.currentTabIndex
正在更新并反映在 Text
小部件中,但当前活动的 BottomNavigationBarItem
UI 并未更新。
感谢您的帮助。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
正如
CupertinoTabScaffold
的 文档 中所述tabBar
属性:因此,在
AppState
中保存CupertinoTabController
实例并更新它的index
是可行的:As mentioned in the docs of
CupertinoTabScaffold
tabBar
property:So, holding instance of
CupertinoTabController
inAppState
and updatingindex
on it works: