ListView
inheritance 继承关系
Object > DiagnosticableTree > Widget > StatelessWidget > ScrollView > BoxScrollView > ListView
BoxScrollView
BoxScrollView 只有一个成员padding,根据滚动方向来添加padding,将另一方向的padding置为0。
BoxScrollView 需要传入的参数有很多,几乎多有传入参数均传给了其父类ScrollView
。
ScrollView
提供滚动(Scrollable)组件、viewport。Scrollable在滚动中回调函数viewportBuilder,提供给viewport偏移量,返回显示视图。
统一处理滚动过程中键盘处理——键盘失去焦点,通过FocusScope.of(context)
获取当前焦点状态,调用unfocus
方法房键盘消失。
ListView总结
在查看集成链路源码中,通过抽象方法划分功能模块。
ScrollView: 负责滚动相关功能
- 集成Scrollable,实现滚动能力。通过集成Scrollable的返回的偏移量,管理自己的viewport。
- 视口创建,Scrollable的回调方法viewportBuilder也很好的解耦了滚动功能和视口创建,视图功能交给使用者ScrollView, 由ScrollView的buildViewport方法实现。
- 视图内容交给子类实现,在buildViewport方法中需要传入具体sliver,而sliver方法是ScrollView的抽象方法,交给子类实现(如BoxScrollView)
BoxScrollView: 负责处理滚动边距问题
- 实现父类ScrollView的buildSlivers方法,处理边距问题
- 具体sliver内容通过抽象方法buildChildLayout,交由子类实现
ListView: 实现
buildChildLayout
方法1
2
3
4
5
6
7
8
9
10
11
12
13
14
15@override
Widget buildChildLayout(BuildContext context) {
if (itemExtent != null) {
return SliverFixedExtentList(
delegate: childrenDelegate,
itemExtent: itemExtent!,
);
} else if (prototypeItem != null) {
return SliverPrototypeExtentList(
delegate: childrenDelegate,
prototypeItem: prototypeItem!,
);
}
return SliverList(delegate: childrenDelegate);
}
GirdView
inheritance
Object > DiagnosticableTree > Widget > StatelessWidget > ScrollView > BoxScrollView > GridView
GridView和ListView都是BoxScrollView子类。边距处理、滚动功能、视口创建均由父类实现。他们均需要实现buildChildLayout
方法,去管理具体silver内容
GirdView
有两个成员girdDelegate和childrenDelegate,这两个类均默认在GirdView构造函数中创建。
- girdDelegate成员是SliverGridDelegate类型,作用是管理sliver布局约束,SliverGridDelegate是抽象类,它有两个子类,一般我们使用也是使用这两个子类:
- SliverGridDelegateWithFixedCrossAxisCount,通过交叉轴sliver个数
- SliverGridDelegateWithMaxCrossAxisExtent, 通过sliver在交叉轴最大尺寸
- childrenDelegate成员是SliverChildDelegate类型,girdView布局管理,给SliverGrid提供最大滚动距离。SliverChildDelegate也是抽象类,也是两个子类,一个用于有builder回调的,一个用于列表:
- SliverChildBuilderDelegate
- SliverChildListDelegate
实现buildChildLayout方法
1 | @override |
GirdView总结
GirdView主要是通过两个成员变量来管理sliver布局和尺寸——childrenDelegate和gridDelegate,这两个成员的类型均是抽象类,也就是说我们完全可以通过集成相应抽象类,去具体实现我们想要的布局,让GirdView灵活性变得大很多。