flutter - 导航到另一个 pageView 或任何 View 时,Bloc 小部件 reftech 数据(重建)
问题描述
上下文:我有一个应用程序可以PageView
在五个屏幕之间导航BottomNavigationBar
,其中一个页面正在使用 Bloc 模式(在未来的版本中几乎所有页面都将使用 Bloc)这些 Blocs 正在从后端服务获取数据以填充 UI与获取的数据。
问题:在小部件树的任何级别的页面之间导航时。Bloc 小部件“重置”并从存储库中重新获取数据。
如下图所示:
小部件树如下:
- 主要.dart
- 主页.dart
- 时间线.dart(屏幕截图中显示的屏幕)
- 主页.dart
尝试过的解决方案:我将其添加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,
)
],
),
),
],
),
),
),
],
),
),
),
),
);
}
这是类的代码timeline.dart
这是home.dart
包含该类的BottomNavigationBar
类的代码
问题:如何在每次小部件重建时阻止块获取数据?
解决方案
我终于明白了这个问题事实证明,这bloc
与问题无关PageView
。
PageView
我将with小部件包装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,用于保存和恢复可以超过小部件的值
感谢这篇很好的中篇文章,它完美地解释了它: 在 Flutter 中使用底部导航栏保持状态
推荐阅读
- python - 为什么t-SNE的学习率这么大?
- curl - 无法制作共享 curl 库
- facebook - 将facebook sdk集成到统一中的问题
- swift - 使用 combine's Publisher 在 SwiftUI Image 中从远程 URL 异步加载图像
- c# - 在运行时创建球形扇区
- node.js - 使用情绪分析检测事件标题是工作还是休闲?
- barcode-scanner - 在 Vaadin 中使用 QuaggaJS 进行条码扫描
- python - TFX / Tensorflow 数据验证 (TFDV) 不适用于数据漂移
- fortran - 关于 Fortran 命令行参数的问题
- javascript - 如何修复 d3.js 中的可扩展树?