上下文:我有一个应用,该应用带有PageView
,可使用BottomNavigationBar
在五个屏幕之间导航,其中一个页面正在使用Bloc模式(几乎所有页面将在将来的版本中使用Bloc。)这些Bloc正在从后端服务中获取数据,以使用获取的数据填充UI。
问题:在窗口小部件树的任何级别的页面之间导航时。 Bloc小部件“重置”并从存储库中重新获取数据。
如下图所示:
小部件树如下:
尝试的解决方案::我将AutomaticKeepAliveClientMixin
添加到了页面类和其他页面,但没有完成。
这是上面截图中显示的页面的构建方法的代码
@override
Widget build(BuildContext context) {
super.build(context);
return DefaultTabController(
length: 4,
child: Scaffold(
backgroundColor: Colors.white,
appBar: _builAppBarWithTabs(),
body: Center(
child: ConstrainedBox(
constraints: BoxConstraints(maxWidth: 1200),
child: ListView(
scrollDirection: Axis.vertical,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(bottom: 150),
child: Container(
height: 800,
child: CustomScrollView(
scrollDirection: Axis.vertical,
slivers: <Widget>[
SliverToBoxAdapter(
child: MasonryGrid(
column: getResponsiveColumnNumber(context, 1, 2, 6),
children: <Widget>[
// First Bloc
BlocProvider(
create: (context) {
BrandBloc(repository: _brandRepository);
},
child: Container(
width: 200,
alignment: Alignment.center,
height: 80,
child: BrandScreen(
brandBloc: context.bloc(),
),
),
),
CategoryScreen(
// Second Bloc
categoryBloc: CategoryBloc(
repository: context.repository(),
),
),
Container(
width: 200,
alignment: Alignment.center,
height: 330,
child: _buildFeaturedItemsList(),
),
Placeholder(
strokeWidth: 0,
color: Colors.white,
)
],
),
),
],
),
),
),
],
),
),
),
),
);
}
here是类timeline.dart
的代码
here是包含home.dart
类的类BottomNavigationBar
的代码
问题:如何在每次重新构建窗口小部件时阻止集团获取数据?
答案 0 :(得分:4)
我终于解决了这个问题
事实证明,这与bloc
无关,而是与PageView
相关的问题。
我将PageView
和PageStorage
小部件包装在一起,如下所示:
final PageStorageBucket bucket = PageStorageBucket(); //PageStorageBucket
static List<Widget> pages = [
Timeline(pageController: pageController, key: PageStorageKey('timeline')),
Search(key: PageStorageKey('search')),
LikeScreen(key: PageStorageKey('like')),
CartScreen(key: PageStorageKey('cart')),
storageService.getFromDisk('api_token') != null
? ProfileScreen(key: PageStorageKey('profile'))
: AuthChooserScreen(key: PageStorageKey('auth')),
];
@override
Widget build(BuildContext context) {
super.build(context);
return SafeArea(
top: true,
bottom: true,
child: Scaffold(
backgroundColor: Colors.white,
key: _scaffoldKey,
//Wrapped PageView with PageStorage
body: PageStorage(
bucket: bucket,
child: PageView(
children: pages,
controller: pageController,
onPageChanged: onPageChanged,
physics: NeverScrollableScrollPhysics(),
),
),
bottomNavigationBar: _buildBottomNavigationBar(),
),
);
}
每个页面都分配了一个PageStorageKey,用于保存和恢复可能超出窗口小部件的值
感谢这篇出色的媒介文章,完美地解释了这一点: Keeping State with the Bottom Navigation Bar in Flutter
答案 1 :(得分:3)
您使用BlocProvider小部件的方式错误 相反,您应该将BlocProvider提取到较高的级别,而在页面“如果您在整个应用程序中使用此bloc的情况下,请从Maby到MaterialApp小部件”之间导航时,将不会重建该BlocProvider。 然后使用BlocBuilder或BlocConsumer将现有Bloc实例提供给子窗口小部件,并在bloc状态更改时自动重建。 BlocBuilder官方文档: https://bloclibrary.dev/#/flutterbloccoreconcepts?id=blocbuilder