一、基本Scrollable
1.1 Recycle
类似RecyclerView,ListView会回收划出屏幕的控件,同时也会预先加载下面的几条。Flutter的回收可以使其被重复利用,也就是Recycle。缓冲区大小不是根据个数而是根据屏幕高度,大约是1/3屏幕,上下都有,可以用cacheExtent调整缓冲区高度。
1.2 分割线
可以用奇偶数来做Divider(),但这不是一个很好的方法:index会偏移。可以使用ListView.seprated来做分割线。
1.3 滚动条跳转(固定高度)
指定Scrollbar()可以实现滚动条效果,但如果不添加itemCount属性,则列表无限长,即使滚动,滚动条也不会有反应;如果不指定itemExtent(这是一个主轴方向的紧约束),首先大幅跳转时会损失性能,其次滚动条可能会抖动。
1.4 Padding
- 在
itemBuilder内加Padding,在视觉上会有padding,但在空白处可以滑动滚动; - 在
ListView.builder外加Padding,在视觉上有padding,空白处不可滑动; - 设置
ListView.builder内的padding属性,会在整个ListView上下留白,而不是元素间的空隙。可以用EdgeInsets.only(bottom: 200)来解决底部项目被FAB挡住的问题。
1.5 空白时显示其他控件
body: false ? Text("加载中") : ListView.builder
1.6 ScrollController
在ListView.builder中设置controller: _controller。例如,设置按下AppBar自动跳到顶部,可以使用以下代码:
AppBar(
title: GestureDetector(
onTap: () {
//_controller.jumpTo(0.0);
_controller.animatedTo(-20.0, duration: ,curve: );
//传入负值,出现到顶上再弹回的效果
} //跳转
)
)
有多个ListView时,也应设置对应的controller。
1.7 physics属性
ListView.builder的physics属性可以用来设置安卓或iOS风格的到顶回弹。例如physics: BouncingScrollPhysics()就是iOS风格的顶部回弹。
二、滑动事件
2.1 Scrollbar
使用iOS风格的Scrollbar可以使用CupertinoScrollbar()。同时设置isAlwaysShown和controller属性可以一直显示scrollbar。
2.2 RefreshIndicator下拉刷新
可以设置color和backgroundColor等属性设置下拉刷新指示器的样式。RefreshIndicator和Scrollbar可以互相嵌套,不要求顺序。
2.3 拦截滚动事件
使用NotificationListener,在onNotication返回true拦截事件。
2.4 Dismissible
在itemBuilder内返回一个Dismissible(),这里的key属性是必传的,例如UniqueKey(),设置onDismissed可以查看滑动方向并设置滑动后的操作,例如从列表中删除。
在Dismissible()中有background或secondaryBackground可以传入一个widget,分别对应左划右划的效果。
设置confirmDismiss为一个async函数,返回false表明滑动后不删除。
设置onResize属性可以在该项消失、屏幕开始变化时不停地调用;movementDuration可以设置滑动的时常,movement后就onResize;dismissThreshold设置滑动多少后消除;direction可以设置滑动方向。
三、其他控件
3.1 3D转轮滚动效果——ListWheelScrollView
- offAxisFraction:偏移数值
- diameterRatio:直径比例
- overAndUnderCenterOpacity:设置上下不透明度
- magnification:放大倍数
- physics:滚动物理效果
- onSelectedItemChanged:选择的内容变化
- 使用
RotatedBox来进行横向滚动
3.2 滚动页面——PageView
- pageSnapping:划到中间可以停住
- scrollDirection:设置滚动方向
- onPageChanged
3.3 ReorderableListView
-
children:List.generate(…)
-
onReorder: (int oldIndex,int newIndex):移动后的新位置和旧位置
-
这里有一个小坑,应该这样写:
onReorder: (int oldIndex,int newIndex){ if(newIndex > oldIndex) newIndex--; //...继续写其他的业务逻辑 }
-
-
在每个ListItem中必须设置单独的key,否则会报错,因为它的排序属性。
ReorderableListView( children: List.generate( 20, (index) => Text("$index",key: UniqueKey()), ) )
3.4 SingleChildScrollView
这个组件一般不推荐用,除非是一般不需要滑动的组件,在屏幕不够大、显示不下的情况下偶尔滑动。