问题
在 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 的滚动动画。
那么有什么方法可以保持嵌套滚动视图中的状态吗?