Flutter列表滚动定位超强辅助库使用示例详解

Danica ·
更新时间:2024-11-13
· 968 次阅读

目录

一、痛点

二、优点

三、使用

1、ListView

2、GridView

3、CustomSrollView

四、说明

1、ViewObserver 的选择

2、isFixedHeight

3、sliverContext 是否需要传

五、可现实的功能

1、获得当前视窗中的子部件信息

2、视频列表自动播放

3、模块定位

六、最后

一、痛点

痛点一:Flutter 官方提供了 ScrollController,调用下方两个方法可以滚动到指定偏移处

void jumpTo(double value) Future<void> animateTo( double offset, { required Duration duration, required Curve curve, })

但是官方没有提供滚动到指定下标位置的功能

痛点二:

为了解决痛点一,业内有很多第三方库实现了这个功能,其中最知名的莫过于谷歌的 scrollable_positioned_list

而这些库都有一些相同的问题:

侵入性强,必须使用他们提供的 Widget 来构建列表视图

不支持 GridView

对此,我决定自己编写一个库(flutter_scrollview_observer)来实现这个功能,以及解决以上的问题。

二、优点

侵入性低,不会限制你的列表视图实现,只要求将列表视图做为 ViewObserverchild,如果不想用了,直接移除掉 ViewObserver 即可。

基于【不会限制你的列表视图实现】这一点, flutter_scrollview_observer 支持所有的列表Widget,如:ListViewGridView,甚至 CustomSrollView

防抖动,如果在滚动到指定下标时,列表尾部的可滚动区域已不足以支撑滚动到相应位置,则会自动滚动到最底部,避免回弹的问题

下面正式介绍一下这个库的使用

三、使用 1、ListView

正常创建和使用 ScrollController 实例

这里你可以使用 ListView 或者 CustomSrollViewSliverList

ScrollController scrollController = ScrollController(); ListView _buildListView() { return ListView.separated( controller: scrollController, ... ); }

创建 ListObserverController 实例并将其传递给 ListViewObserver

ListObserverController observerController = ListObserverController(controller: scrollController); ListViewObserver( controller: observerController, child: _buildListView(), ... )

注意:创建 ListObserverController 实例时需要传入列表的 ScrollController 实例。 这一步很重要,因为 flutter_scrollview_observer 内部实现原理是基于官方 ScrollController 提供的 jumpToanimateTo 方法

现在即可滚动到指定下标位置了

// 无动画滚动至下标位置 observerController.jumpTo(index: 100) // 动画滚动至下标位置 observerController.animateTo( index: 100, duration: const Duration(seconds: 1), curve: Curves.ease, );

2、GridView

内容与 ListView 基本一致

正常创建和使用 ScrollController 实例

Widget _buildGridView() { return GridView.builder( ... controller: scrollController, ... ); }

创建 GridObserverController 实例并将其传递给 GridViewObserver

GridObserverController observerController = GridObserverController(controller: scrollController); GridViewObserver( controller: observerController, child: _buildGridView(), )

现在即可滚动到指定下标位置了

observerController.jumpTo( index: 40, ); observerController.animateTo( index: 40, duration: const Duration(seconds: 1), curve: Curves.ease, ); 3、CustomSrollView

支持 SliverListSliverGrid 混合使用的情况!

如上图所示,CustomSrollViewslivers 中包含有 SliverListSliverGrid

点击右下角第一个按钮可滚动到 SliverList 的第 29

点击第二个按钮可滚动到 SliverGrid 的第 10 的子部件所在行

正常创建和使用 ScrollController 实例

Widget _buildScrollView() { return CustomScrollView( controller: scrollController, // scrollDirection: Axis.horizontal, slivers: [ _buildSliverListView(), _buildSliverGridView(), ], ); }

正常创建你的 SliverListSliverGrid,并将它们的 BuildContext 记录起来

Widget _buildSliverListView() { return SliverList( delegate: SliverChildBuilderDelegate( (ctx, index) { _sliverListCtx ??= ctx; ... }, ... ), ); } Widget _buildSliverGridView() { return SliverGrid( ... delegate: SliverChildBuilderDelegate( (BuildContext context, int index) { _sliverGridCtx ??= context; ... }, ... ), ); }

创建 SliverObserverController 实例并将其传递给 SliverViewObserver

注意:在 sliverListContexts 里返回刚才记录的两个 SliverBuildContext

SliverObserverController observerController = SliverObserverController(controller: scrollController); SliverViewObserver( controller: observerController, child: _buildScrollView(), sliverListContexts: () { return [ if (_sliverListCtx != null) _sliverListCtx!, if (_sliverGridCtx != null) _sliverGridCtx!, ]; }, ... ),

现在即可滚动到指定下标位置了

observerController.animateTo( sliverContext: _sliverListCtx, index: 29, duration: const Duration(milliseconds: 300), curve: Curves.easeInOut, ); observerController.animateTo( sliverContext: _sliverGridCtx, index: 10, duration: const Duration(milliseconds: 300), curve: Curves.easeInOut, ); 四、说明 1、ViewObserver 的选择

建议使用相应的 ViewObserver

如果是 ListView 或者纯 SliverList,建议使用 ListViewObserver

如果是 GridView 或者纯 SliverGrid,建议使用 GridViewObserver

如果是 SliverListSliverGrid,则使用 SliverViewObserver

这样在 onObserve 回调中拿到数据模型后不用再对其进行类型判断与转换。

2、isFixedHeight

子部件为固定高度的情况下,请设置 isFixedHeighttrue,以提升性能!

observerController.jumpTo( index: 100, isFixedHeight: true ); observerController.animateTo( index: 100, isFixedHeight: true, duration: const Duration(seconds: 1), curve: Curves.ease, ); 3、sliverContext 是否需要传 jumpTo({ required int index, BuildContext? sliverContext, bool isFixedHeight = false, }) animateTo({ required int index, required Duration duration, required Curve curve, BuildContext? sliverContext, bool isFixedHeight = false, })

如上,jumpToanimateTo 方法中都有一个 sliverContext 参数,这是用来指定哪个 sliver 进行滚动操作的。

如果不传 sliverContext,则默认会是列表中的第一个 sliver,只有你想让非第一个 sliver 进行滚动的时候才需要传该值

五、可现实的功能 1、获得当前视窗中的子部件信息

如上图控制台所示,在滚动的过程中可以实时获取正在显示的子部件的数据。

2、视频列表自动播放

这种功能很常见,在列表滚动的时候,指定区域内的被命中的视频便会自动进行播放。

3、模块定位

一般详情页中都会有的功能,在列表视图滚动的时候,顶部定位导航视图跟着更新下标,点击导航视图某个下标则会定位到对应的模块

六、最后

如果这个库对你很有帮助,请不吝给个 star

GitHub: flutter_scrollview_observer

以上就是Flutter列表滚动定位超强辅助库使用示例详解的详细内容,更多关于Flutter列表滚动定位辅助库的资料请关注软件开发网其它相关文章!



示例 flutter 定位

需要 登录 后方可回复, 如果你还没有账号请 注册新账号