自定义ProxyWidget组件
业务场景
滑动选择,根据手势判断选中的元素
需求分析
- 监听手势滑动
- 根据手势位置判断元素是否被选中
- 通知子元素做选中UI展示
监听手势滑动
通过GestureDetector
包裹识别区域,默认使用:
- onHorizontalDragStart
- onHorizontalDragUpdate
- onHorizontalDragEnd
三个方法,判断此次滑动区域起始点和结束点,以及滑动过程中选中部分。
根据手势位置判断元素是否被选中
自定义ProxyWidget
- 标记当前widget标识,当前用下标做标识,方便状态同步。
- 实现
createElement
方法,创建一个ProxyElement
子类; - ProxyElement根据
unmount
和mount
生命周期,上报父容器元素自身挂载状态。 - ProxyElement对象提供判断是否在父容器手势范围内,其中用到了renderObject,renderObject是Element的属性(Element>ComponentElement>ProxyElement)
1
2
3
4
5bool containsOffset(RenderObject? ancestor, Offset offset) {
final box = renderObject as RenderBox;
final rect = box.localToGlobal(Offset.zero, ancestor: ancestor) & box.size;
return rect.contains(offset);
}滑动过程中,获取手势当前位置信息
在监听手势过程中,手势的回调都会返回position信息。
_elements即子元素上报统计的集合
1 | int _findIndexOfSelectable(Offset offset) { |
熟悉一下ProxyWidget常用子类
- ParentDataWidget
- InheritedWidget
- NotificationListener
ProxyWidget和ProxyElement的主要功能
ProxyWidget
:
- 实现
createElement
方法,创建一个ProxyElement
子类; - 定义widget对外属性
- 提供子类接口
- 例如
InheritedWidget
的updateShouldNotify
,InheritedWidget
子类需要实现updateShouldNotify
,从而决定是否通知重绘等; updateShouldNotify
提升到widget层,而不是在Element的notifyClients
中判断,是为了让使用者不关注Element层。
- 例如
ProxyElement
- 重写
notifyClients
,用于对旧的数据进行对比,判断是否通知重绘等操作 - 根据Element的生命周期,实现自定义业务需求。
- 也可以在
ProxyElement
添加自定义方法,提供给业务使用。