一、 可滚动组件
1.可滚动组件 :用于显示列表和长布局,ListView、GridView等。 可滚动组件直接或者间接包含一个Scrollable组件 ;
- axisDirection 滚动方向
- physics: 接受一个Scrollphysics 类型的对象,它决定可滚动组件如何响应用户操作,比如用户滚动完抬起手指后,继续执行动画; BouncingScrollPhysics:下弹效果;
- controller: 接受一个ScrollController对象;
- ScrollBar : material风格滚动指示器 ,滚动条
- CupertinoScrollbar : iOS风格滚动条
二、 SingleChildScrollView
- SingleChildScrollView 只接收一个子组件,只在期望的内容不超过屏幕太多时使用,主要是因为其 不支持 Sliver 的延迟实例化模型;
- reverse : 反方向滚动;
- primary:主要的 是否使用widget 树 默认的primaryScrollController ;
- ListView : 最常用的可滚动组件之一,可沿一个方向线性排布所有子组件,也支持基于Sliver延迟构建模型
、、、
ListView({
...
//可滚动widget公共参数 Axis scrollDirection = Axis.vertical, bool reverse = false, ScrollController controller, bool primary, ScrollPhysics physics, EdgeInsetsGeometry padding, //ListView各个构造函数的共同参数
double itemExtent, bool shrinkWrap = false, bool addAutomaticKeepAlives = true, bool addRepaintBoundaries = true, double cacheExtent, //子widget列表 List children = const [], }) 、、、
- itemExtent : 该参数如果不为 null ,则会强制children 的长度为itemExtend的值;
- shrinkWrap : 是否根据子组件的总长度来设置 Listview的长度,默认是false ;ListView的会在滚动方向尽可能多的占用空间。当ListView在一个无边界(滚动方向上)的容器中时,shrinkWrap必须为true
- addAutomaticKeepAlives: 是否将列表项包裹在AutomaticKeepAlive组件中; 这样可以在列表滑出视口时不被垃圾回收,如果类别项自己维护其KeepAlive状态 。,此参数必须为true;
- addRepaintBoundaries: 避免重绘,如果维护包裹在RepaintBoundary 组件中,此参数必须设置为false;
三、 默认构造函数
- 构造函数有一个children 参数,接受一个Widget列表 list;只适合少量子组件。
- ListView.builder 适合类别项比较多或者无限的情况,只有当子组件真正显示的时候才会被创建,也就是说 该构造函数通过ListView sliver的懒加载; 、、、 ListView.builder({ @required IndexedWidgetBuilder itemBuilder, int itemCount, ... }) 、、、
- itemBuilder: 列表项的构建器 类型为: indexdWidgetBuilder ,返回一个widget,当列表滚动到具体index位置时 会调用该构建器构建列表项
- itemCount : 列表项的数量,如果为 null 则为无限列表
- ListView.separated 可以在生成的列表项之间添加分割组件,比ListView.builder多了一个separatorBuilder 参数 分割线; 、、、 //每次生成20个单词 generateWordPairs().take(20).map((e) => e.asPascalCase).toList() 、、、 Flex自动拉伸ListView以填充剩余空间 Column+Expanded来实现 、、、 @override Widget build(BuildContext context) { return Column(children: [ ListTile(title:Text("商品列表")), Expanded( child: ListView.builder(itemBuilder: (BuildContext context, int index) { return ListTile(title: Text("$index")); }), ), ]); } 、、、
四、 GridView
- GridView 构造二维列表 、、、 GridView({ Axis scrollDirection = Axis.vertical, bool reverse = false, ScrollController controller, bool primary, ScrollPhysics physics, bool shrinkWrap = false, EdgeInsetsGeometry padding, @required SliverGridDelegate gridDelegate, //控制子widget layout的委托 bool addAutomaticKeepAlives = true, bool addRepaintBoundaries = true, double cacheExtent, List children = const [], }) 、、、 重点 : gridDelegate 类型是SliverGridDelegate 作用是: 控制GridView子组件如何排练 layout; Flutter提供了两个 SliverGridDelegate的子类 SliverGridDelegateWithFixedCrossAxisCount和 SliverGridDelegateWithMaxCrossAxisExtent;
- SliverGridDelegateWithFixedCrossAxisCount({ @required double crossAxisCount, // 横轴子元素的数量此属性值确定后子元素在横轴的长度就确定了,即ViewPort横轴长度除以crossAxisCount的商。 double mainAxisSpacing = 0.0, // 主轴方向的间距 double crossAxisSpaceing = 0.0 , //横轴方向子元素的间距 double childAspactRatio = 1.0 , // 子元素在横轴长度和主轴长度的比列;
- GridView.count : 构造函数内部使用了SliverGridDelegateWithFixedCrossAxisCount我们通过它可以快速的创建横轴固定数量子元素的GridView
-
SliverGridDelegateWithMaxCrossAxisExtent : 该子类实现了一个横轴子元素为固定的最大长度的layout算法 其构造函数:
、、、 SliverGridDelegateWithMaxCrossAxisExtent({ double maxCrossAxisExtent, //子元素在横轴上的最大长度,之所以是“最大”长度,是因为横轴方向每个子元素的长度仍然是等分的 double mainAxisSpacing = 0.0, double crossAxisSpacing = 0.0, double childAspectRatio = 1.0, //子元素横轴和主轴的长度比为最终的长度比 }) 、、、比 6. GridView.extent : 快速的创建纵轴元素为固定最大长度的GridView 7. GridView.builder : 前面的GridView 都需要一个widget数组作为子元素 ,前面的方式都会提前将所有子widget都构建好 ,所以只适用于 widget较少时 ,当较多的时候 ,我们需要通过GridView.builder 来动态创建子widget; 、、、 GridView.builder( ... @required SliverGridDelegate gridDelegate, @required IndexedWidgetBuilder itemBuilder, //为子widget构建器 ) 、、、
五、 CustomScrollView
- CustomScrollView 相当于胶水 把独立可滚动组件
六 、 滚动监听及控制
- ScrollController :间接继承自 Listenable ,可以根据ScrollController 来监听滚动事件 Eg: controller.addListener ( () => print(controller.offset))
- NotificationListener 和ScrollController不同
- 通过NotificationListener可以在从可滚动组件到widget树根之间任意位置都能监听。而ScrollController只能和具体的可滚动组件关联后才可以。
- 收到滚动事件后获得的信息不同;NotificationListener在收到滚动事件时,通知中会携带当前滚动位置和ViewPort的一些信息,而ScrollController只能获取当前滚动位置。 ScrollNotification 包括一个metrics属性 类型是ScrollMetrics ,该属性包含当前viewPort滚动的位置等信息
- pixels: 当前滚动位置
- maxScrollExtent: 最大可滚动长度
- extentBefore: 滚出viewPort顶部的长度, 顶部滚出屏幕上方的列表长度
- extentInside: viewPort内部长度;
- extentAfter: 列表中未划入viewport部分的长度
- atEdge: 是否划到可滚动组件的边界