flutter - 即使在使用键后 Flutter TabbarView 也不会保持滚动位置
问题描述
问题
在 Imgur 上观看视频:Imgur
您也可以在这里观看视频:Cloudinary
正如您在视频中看到的那样,滚动位置没有被保持。看起来页面正在一起滚动。
基本应用结构
我正在使用带有 SliverAppBar 和 TabBarView 的 NestedScrollView 来实现简单的滚动效果。标签栏显示不同的页面,这些页面反过来使用Provider进行状态管理,我正在返回 CustomScrollView。
主页 :
DefaultTabController(
length: 3,
child: Scaffold(
body: NestedScrollView(
headerSliverBuilder: (context, innerBoxIsScrolled) => [
SliverAppBar(
floating: true,
pinned: true,
snap: true,
forceElevated: true,
title: Text('Title'),
bottom: TabBar(
tabs: [
Tab(
icon: Icon(Icons.extension_rounded),
),
Tab(
icon: Icon(Icons.folder_rounded),
),
Tab(
icon: Icon(Icons.settings_rounded),
)
],
),
),
],
body: TabBarView(
children: [
PageStorage(
bucket: _bucket,
child: ExtensionsView(
key: PageStorageKey('extensions_view'),
),
),
PageStorage(
bucket: _bucket,
child: VideosView(
key: PageStorageKey('videos_view'),
),
),
PageStorage(
bucket: _bucket,
child: SettingsView(
key: PageStorageKey('settings'),
),
),
],
),
),
),
);
标签栏查看页面
return ViewModelBuilder<ExtensionsViewModel>.reactive(
viewModelBuilder: () => ExtensionsViewModel(),
onModelReady: (model) => model.fetchData(),
builder: (context, model, child) => CustomScrollView(
slivers: [
if (model.isBusy)
SliverList(
delegate: SliverChildBuilderDelegate(
(context, index) {
return FilledVideoCard.loading(
borderRadius: BorderRadius.zero,
);
},
childCount: 3,
),
)
else
SliverList(
delegate: SliverChildBuilderDelegate(
(context, index) {
final data = model.extensions[index];
return FilledVideoCard(
key: ObjectKey(data),
title: data.title,
price: data.price,
date: data.date,
image: data.image,
tags: [data.version, ...data.tags],
borderRadius: BorderRadius.zero,
onTap: () {},
);
},
childCount: model.extensions.length,
),
),
],
),
)
笔记 :
- 在所有 tabbarview 页面中,我使用AutomaticKeepAliveClientMixin来确保该页面只创建一次。
- 在所有 tabbarview 页面中,我都返回了 CutomScrollView。
到目前为止我尝试过的
我尝试了不同的方法来保持 tabbarview 内的滚动位置。
PageStorageKey('page')
PageStorageKey('page')
和PageStorage()
ScrollController
使用 CustomScrollView- 通过小部件构造函数传递
PageStorageKey
给 CustomScrollView
我尝试了以上所有方法来保留滚动位置,但正如您在视频中看到的那样,滚动位置没有保持不变。只有直接将 CustomScrollView 添加到 TabbarView 时,滚动位置才会被保留。但在我的情况下,CustomScrollView 嵌套在一个有状态的小部件中,该小部件使用 Stacked(提供)进行状态管理和未维护的滚动位置。
但是,如果我在每个页面中为 CustomScrollView 分配一个控制器,那么我就会失去 SliverAppBar 的滚动动画。
那么有什么方法可以保持嵌套滚动视图中的状态吗?
解决方案
推荐阅读
- python - seaborn.violinplot() KeyError 的未知原因
- node.js - 为什么我的网络响应时间加起来不等于 Chrome 开发工具报告的总时间?WSL2 上的节点
- php - 找不到类 'phpseclib\Crypt\Random'
- c++ - 有没有更好的方法来实现成员函数 row() 的 const 版本而不使用 const_cast?
- php - Laravel,我如何捕捉发回给我的请求
- python - 如何使用python有条件地从txt文件中删除行序列
- javascript - 谷歌图表只显示了一半
- python-3.x - 尝试使用 MinMaxScaler() 缩放数据帧 (X_train)。抛出 ValueError :数组形状 = (0,) 至少需要 1
- android - AppCompatActivity 下的按钮不会在运行时自动更改为 AppCompatButton?
- machine-learning - 主题检测分类模型的推文数据集