-
-
Notifications
You must be signed in to change notification settings - Fork 44
1、监听滚动视图中正在显示的子部件
ListViewObserver
的参数说明:
参数 | 必传 | 说明 |
---|---|---|
child |
是 | 将构建的 ListView 做为 ListViewObserver 的子部件 |
sliverListContexts |
否 | 该回调中返回需要被观察的 ListView 的 BuildContext ,在需要精确指定 BuildContext 时才会用到该参数 |
onObserve |
否 | 该回调可以监听到当前 第一个 Sliver 中正在显示中的子部件的相关信息 |
onObserveAll |
否 | 该回调可以监听到当前 所有 Sliver 正在显示中的子部件的相关信息,当有多个 Sliver 时才需要使用到这个回调 |
leadingOffset |
否 | 列表头部的计算偏移量,从该偏移量开始计算首个子部件 |
dynamicLeadingOffset |
否 |
leadingOffset 的动态版本,在列表头部的计算偏移量不确定时使用,优先级高于 leadingOffset
|
toNextOverPercent |
否 | 首个子部件被遮挡的百分比达到该值时,则下一个子部件为首个子部件,默认值为 1
|
autoTriggerObserveTypes |
否 | 用于设置自动触发观察的时机 |
triggerOnObserveType |
否 | 用于配置触发 [onObserve] 或 [onObserveAll] 回调的前提 |
customHandleObserve |
否 | 用于自定义观察逻辑,当自带的处理逻辑不符合你的需求时使用 |
customTargetRenderSliverType |
否 | 在保持原来的观察逻辑上,告诉该库要处理的 RenderSliver ,以支持对第三方库构建的列表进行观察。 |
使用上比较简单,应用范围广,一般情况下只需要使用该方式
构建 ListViewObserver
,将 ListView
实例传递给 child
参数
ListViewObserver(
child: _buildListView(),
onObserve: (resultModel) {
print('firstChild.index -- ${resultModel.firstChild?.index}');
print('displaying -- ${resultModel.displayingChildIndexList}');
},
)
默认是 ListView
在滚动的时候才会观察到相关数据。
如果需要,可以使用 ListObserverController
进行手动触发一次观察
// 创建 `ListObserverController` 实例
ListObserverController controller = ListObserverController();
...
// 传递给 `ListViewObserver` 的 `controller` 参数
ListViewObserver(
...
controller: controller,
...
)
...
// 手动触发一次观察
controller.dispatchOnceObserve();
dispatchOnceObserve
方法的定义:
以 ListObserverController
的为例
Future<ListViewOnceObserveNotificationResult> dispatchOnceObserve({
BuildContext? sliverContext,
bool isForce = false,
bool isDependObserveCallback = true,
})
dispatchOnceObserve
的参数说明:
参数 | 必传 | 说明 |
---|---|---|
sliverContext |
否 | 滚动视图的 BuildContext ,只有在 CustomScrollView 有多个 Sliver 时才会使用到 |
isForce |
否 | 是否强制观察,等同于 ObserverTriggerOnObserveType.directly
|
isDependObserveCallback |
否 | 是否依赖于判断 onObserve 等回调有没有实现,如果传 true ,即使没有实现对应的回调,也可以拿到观察结果 |
其返回值可以直接拿到观察的结果!
使用上相对复杂,应用范围小,存在多个
Sliver
时才有可能会用到该方式
具体说明
BuildContext? _sliverListViewContext;
创建 ListView
,并在其 builder
回调中,将 BuildContext
记录起来
ListView _buildListView() {
return ListView.separated(
itemBuilder: (ctx, index) {
if (_sliverListViewContext != ctx) {
_sliverListViewContext = ctx;
}
...
},
...
);
}
构建 ListViewObserver
ListViewObserver(
child: _buildListView(),
sliverListContexts: () {
return [if (_sliverListViewContext != null) _sliverListViewContext!];
},
onObserveAll: (resultMap) {
final model = resultMap[_sliverListViewContext];
if (model == null) return;
// 打印当前正在显示的第一个子部件
print('firstChild.index -- ${model.firstChild?.index}');
// 打印当前正在显示的所有子部件下标
print('displaying -- ${model.displayingChildIndexList}');
},
)
默认是 ListView
在滚动的时候才会观察到相关数据。
如果需要,可以使用 ListViewOnceObserveNotification
进行手动触发一次观察
ListViewOnceObserveNotification().dispatch(_sliverListViewContext);
用于设置自动触发观察的时机,定义如下:
final List<ObserverAutoTriggerObserveType>? autoTriggerObserveTypes;
enum ObserverAutoTriggerObserveType {
scrollStart,
scrollUpdate,
scrollEnd,
}
其默认值为 [.scrollStart, .scrollUpdate, .scrollEnd]
枚举值说明:
枚举值 | 描述 |
---|---|
scrollStart |
开始滚动 |
scrollUpdate |
滚动中 |
scrollEnd |
结束滚动 |
用于配置触发 [onObserve]
和 [onObserveAll]
回调的前提,定义如下:
final ObserverTriggerOnObserveType triggerOnObserveType;
enum ObserverTriggerOnObserveType {
directly,
displayingItemsChange,
}
其默认值为 .displayingItemsChange
枚举值说明:
枚举值 | 描述 |
---|---|
directly |
观察到数据后直接将数据返出 |
displayingItemsChange |
当列表子部件进出或数量发生变化时将观察到的数据返出 |
仅支持
CustomScrollView
用于观察当前 CustomScrollView
的 Viewport
中有哪些指定的 Sliver
正在展示
SliverViewObserver(
child: _buildScrollView(),
sliverContexts: () {
return [
if (grid1Context != null) grid1Context!,
if (swipeContext != null) swipeContext!,
if (grid2Context != null) grid2Context!,
];
},
onObserveViewport: (result) {
firstChildCtxInViewport = result.firstChild.sliverContext;
if (firstChildCtxInViewport == grid1Context) {
debugPrint('current first sliver in viewport - gridView1');
} else if (firstChildCtxInViewport == swipeContext) {
debugPrint('current first sliver in viewport - swipeView');
} else if (firstChildCtxInViewport == grid2Context) {
debugPrint('current first sliver in viewport - gridView2');
}
},
)
需要注意的是,这里的
sliverContexts
参数传入的是每个外层Sliver
的BuildContext
!
如下结构中,我们需要用到的是 SliverPadding
的 BuildContext
,而不是 SliverList
的 BuildContext
SliverPadding(
padding: EdgeInsets.only(bottom: 10),
sliver: SliverList(
delegate: SliverChildBuilderDelegate(
(context, index) {
...
},
...
),
),
);
仅支持
ListViewObserver
和GridViewObserver
在保持原来的观察逻辑上,告诉该库要处理的 RenderSliver
,目的是为了支持对第三方库构建的列表进行观察。
customTargetRenderSliverType: (renderObj) {
// 告诉该库它需要观察什么类型的RenderObject
return renderObj is ExtendedRenderSliverList;
},
该回调用于自定义观察逻辑,当自带的处理逻辑不符合你的需求时使用。
customHandleObserve: (context) {
// 完全自定义你的观察逻辑
final _obj = ObserverUtils.findRenderObject(context);
if (_obj is RenderSliverList) {
ObserverCore.handleListObserve(context: context);
}
if (_obj is RenderSliverGrid || _obj is RenderSliverWaterfallFlow) {
return ObserverCore.handleGridObserve(context: context);
}
return null;
},
仅支持
SliverViewObserver
该回调用于对原来的观察逻辑进行补充,原来只处理 RenderSliverList
、RenderSliverFixedExtentList
和 RenderSliverGrid
。
extendedHandleObserve: (context) {
// 在对原来的观察逻辑进行拓展
final _obj = ObserverUtils.findRenderObject(context);
if (_obj is RenderSliverWaterfallFlow) {
return ObserverCore.handleGridObserve(context: context);
}
return null;
},
监听模型的基类
属性 | 类型 | 描述 |
---|---|---|
sliver |
RenderSliver |
当前 sliver
|
visible |
bool |
sliver 是否可见 |
displayingChildIndexList |
List<int> |
当前现在显示的子部件的下标 |
axis |
Axis |
sliver 的方向 |
scrollOffset |
double |
sliver 的偏移量 |
继承自
ObserveModel
,ListView
和SliverList
专用的监听模型
属性 | 类型 | 描述 |
---|---|---|
sliver |
RenderSliverMultiBoxAdaptor |
当前 sliver
|
firstChild |
ListViewObserveDisplayingChildModel |
当前第一个正在显示的子部件数据模型 |
displayingChildModelList |
List<ListViewObserveDisplayingChildModel> |
当前正在显示的所有子部件数据模型 |
继承自
ObserveModel
,GridView
和SliverGrid
专用的监听模型
属性 | 类型 | 描述 |
---|---|---|
sliverGrid |
RenderSliverGrid |
当前 sliver
|
firstGroupChildList |
List<GridViewObserveDisplayingChildModel> |
当前第一排正在显示的所有子部件数据模型 |
displayingChildModelList |
List<GridViewObserveDisplayingChildModel> |
当前正在显示的所有子部件数据模型 |
当前正在显示的子部件的数据信息
属性 | 类型 | 描述 |
---|---|---|
sliver |
RenderSliver |
当前 sliver
|
viewport |
RenderViewportBase |
当前 sliver 对应的 viewport
|
index |
int |
子部件的下标 |
renderObject |
RenderBox |
子部件对应的 RenderBox 实例 |
当前正在显示的子部件的数据信息,是对
ObserveDisplayingChildModel
的补充
属性 | 类型 | 描述 |
---|---|---|
axis |
Axis |
sliver 的方向 |
size |
Size |
子部件的大小 |
mainAxisSize |
double |
子部件主轴方向上的大小 |
scrollOffset |
double |
sliver 的偏移量 |
layoutOffset |
double |
子部件相应于 sliver 的偏移量 |
leadingMarginToViewport |
double |
子部件距离视口顶部的距离 |
trailingMarginToViewport |
double |
子部件距离视口尾部部的距离 |
visibleMainAxisSize |
double |
子部件自身显示的大小 |
visibleFraction |
double |
子部件自身大小在 sliver 所显示大小中的的占比 |
displayPercentage |
double |
子部件自身大小显示的占比 |