flutter_sliver_tracker
滑動曝光埋點框架,支援SliverList、SliverGrid
什麼是滑動曝光埋點
滑動曝光埋點用於滑動列表元件中的模組曝光,例如Flutter中的SliverList
、SliverGrid
。
當SliverList
中的某一個行(或列)移動到ViewPort
中,並且顯示比例超過一定閾值時,我們把這個事件記為一次滑動曝光事件。
當然我們對滑動曝光有一些額外的要求:
- 需要滑出一定比例的時候才出發曝光(已實現)
- 滑動速度快時不觸發曝光事件(需要throttle)
- 滑出視野的模組,再次滑入視野時需要再次上報(已實現)
- 模組在視野中上下反覆移動只觸發一次曝光(還未實現)
執行Demo
- 克隆程式碼到本地: git clone git@github.com:SBDavid/flutter_sliver_tracker.git
- 切換工作路徑: cd flutter_sliver_tracker/example/
- 啟動模擬器
- 執行: flutter run
內部原理
滑動曝光的核心難點是計算元件的露出比例。也是說我們需要知道ListView
中的元件的總高度
、當前顯示高度
。
這兩個高度做除法就可以得出比例。
元件總高度
元件的總高度可以在renderObject
中獲取。我們可以獲取renderObject
下的size
屬性,其中包含了元件的長寬。
當前顯示高度
顯示高度可以從SliverGeometry.paintExtent
中獲取。
使用文件
1. 安裝
dependencies:
flutter_sliver_tracker: ^1.0.0
複製程式碼
2. 引用外掛
import 'package:xm_sliver_listener/flutter_sliver_tracker.dart';
複製程式碼
3. 傳送滑動埋點事件
3.1 通過ScrollViewListener
捕獲滾動事件,ScrollViewListener
必須包裹在CustomScrollView
之上。
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
// 通過ScrollViewListener捕獲滾動事件
body: ScrollViewListener(
child: CustomScrollView(
slivers: <Widget>[
],
),
),
);
}
}
複製程式碼
3.2 在SliverToBoxAdapter
中監聽滾動停止事件,並計算顯示比例
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
// 通過ScrollViewListener捕獲滾動事件
body: ScrollViewListener(
child: CustomScrollView(
slivers: <Widget>[
SliverToBoxAdapter(
// 監聽停止事件,如果在頁面上展示比例,可以自行setState
child: SliverEndScrollListener(
onScrollInit: (SliverConstraints constraints, SliverGeometry geometry) {
// 顯示高度 / sliver高度
Fluttertoast.showToast(msg: "展示比例:${geometry.paintExtent / geometry.scrollExtent}");
},
onScrollEnd: (ScrollEndNotification notification,
SliverConstraints constraints,
SliverGeometry geometry) {
Fluttertoast.showToast(msg: "展示比例:${geometry.paintExtent / geometry.scrollExtent}");
},
child: Container(
height: 300,
color: Colors.amber,
),
),
),
],
),
),
);
}
}
複製程式碼
3.3 在SliverList
和SliverGrid
中監聽滾動停止事件,並計算顯示比例
- itemLength:列表項佈局高度
- displayedLength:列表項展示高度
- 如果需要在widget中顯示高度,可以自行setState
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
// 通過ScrollViewListener捕獲滾動事件
body: ScrollViewListener(
child: CustomScrollView(
slivers: <Widget>[
SliverList(
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
// 監聽滾動停止
return SliverMultiBoxScrollEndListener(
debounce: 1000,
child: Container(
height: 300,
color: Colors.redAccent,
child: Center(
child: Text("SliverList Item", style: TextStyle(fontSize: 30, color: Colors.white))
),
),
onScrollInit: (double itemLength, double displayedLength) {
Fluttertoast.showToast(msg: "顯示高度:${displayedLength}");
},
onScrollEnd: (double itemLength, double displayedLength) {
Fluttertoast.showToast(msg: "顯示高度:${displayedLength}");
},
);
},
childCount: 1
),
),
],
),
),
);
}
}
複製程式碼
3.4 在SliverList
和SliverGrid
中監聽滾動更新事件,並計算顯示比例
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
// 通過ScrollViewListener捕獲滾動事件
body: ScrollViewListener(
child: CustomScrollView(
slivers: <Widget>[
SliverList(
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
// 監聽滾動更新事件
return SliverMultiBoxScrollUpdateListener(
onScrollInit: (double percent) {
// percent 列表項顯示比例
},
onScrollUpdate: (double percent) {
// percent 列表項顯示比例
},
debounce: 1000,
// percent 列表項顯示比例
builder: (BuildContext context, double percent) {
return Container(
height: 200,
color: Colors.amber.withAlpha((percent * 255).toInt()),
child: Center(
child: Text("SliverList Item Percent ${percent.toStringAsFixed(2)}", style: TextStyle(fontSize: 30, color: Colors.white))
),
);
},
);
},
childCount: 6
),
),
],
),
),
);
}
}
複製程式碼