0%

Flutter 各种列表曝光方案

Flutter 各种列表曝光方案

目前的曝光有两大场景:播放器可视播放和元素曝光
其中元素曝光还需要细分,有主轴方向滑动曝光,还有混合纵轴方向滑动曝光

场景一:滑动中可视元素内选取元素播放或者停止播放

场景特点

需要在滑动中获取当前可视元素和移除可视范围的元素

  1. 先判断移除移除可视的元素是否存在播放,如果有,停止播放。
  2. 在上一步执行完毕之后,判断新的可视元素中是否含符合播放标准
  3. 开启下一轮播放
  4. 播放结束前没有被划走,继续监测其他符合播放的元素播放

曝光特点

  1. 实时监听滑动中视口内元素变化
  2. 在监听回调中需要同时拿到当前所有可视元素,进行规则匹配

技术方案

flutter_scrollview_observer

API
1
2
3
4
5
/// The callback of getting observed result map.
final Function(Map<BuildContext, M>)? onObserveAll;

/// The callback of getting observed result for first sliver.
final Function(M)? onObserve;

sliverListContexts如果不为null,列表会通过element.visitChildren方法获取的sliverlist列表。

onObserveAll :是返回所有sliverlist回调

注意:onObserveAll返回所有sliverlist,并不能一一绑定。需要通过函数返回的Map实例的key进行查找。

onObserve :是返回第一个sliverlist回调

场景二:可视曝光

元素进入屏幕视口内回调,一般用于曝光打点

场景特点

  1. 用于列表元素曝光打点

曝光特点

  1. 每次曝光处理,元素独自处理,和列表其他元素曝光没有耦合。

技术方案

flutter_exposure

  • ScrollDetailProvider嵌套滑动列表,监听滑动通知并根据需求转化通知到子组件
  • Exposure嵌套需要统计的单个元素,Exposure接受ScrollDetailProvider转化的通知,根据自身的偏移量判断是否在视口内。
  • ExposureController实例可以绑定多个Exposure,通过调用reCheckExposeState方法手动获取一遍当前视口曝光情况

场景三:可视曝光——特殊组合

我们在监测主轴曝光的同时,对特殊元素需要监测纵轴方向曝光。

场景特点

  • 曝光列表中特殊元素曝光
  • 适用于任何renderObject

曝光特点

  • 每次曝光处理,元素独自处理,和列表其他元素曝光没有耦合。

技术方案

visibility_detector
个人认为效率不高,而且回调次数较多。

  • 需要监听的组件通过该三方组件直接嵌套

  • 监听onVisibilityChanged回调,通过可视比例判断是否满足曝光

  • 在元素paint的方法中调用元素(PaintingContext)的addCompositionCallback方法,

  • 在上述方法中,调用计算任务去判断可视比例

  • 计算任务,通过获取父级列表(到顶端),通过recttransform计算当前元素的bounds,组合成VisibilityInfo

    1
    2
    3
    4
    5
    final List<ContainerLayer> ancestors = <ContainerLayer>[ContainerLayer()];
    while (ancestor != null && ancestor.parent != null) {
    ancestors.add(ancestor);
    ancestor = ancestor.parent;
    }
  • VisibilityInfo中有visibleBounds——实际可视的区域,visibleFraction——显示比例