作者 | 弗拉德 来源 | 弗拉德(公众号:fulade_me)
ListView ListView
是在移动端非常常见的控件,在大多数的展示场景中都离不开ListView
。在Flutter
中对ListView
的封装也非常好,简单几行代码就可以满足我们布局一个滚动列表的需求。
先来看一下构造函数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 ListView({ Key key, Axis scrollDirection = Axis.vertical, bool reverse = false , ScrollController controller, bool primary, ScrollPhysics physics, bool shrinkWrap = false , EdgeInsetsGeometry padding, this .itemExtent, bool addAutomaticKeepAlives = true , bool addRepaintBoundaries = true , bool addSemanticIndexes = true , double cacheExtent, List <Widget> children = const <Widget>[], int semanticChildCount, DragStartBehavior dragStartBehavior = DragStartBehavior.start, ScrollViewKeyboardDismissBehavior keyboardDismissBehavior = ScrollViewKeyboardDismissBehavior.manual, })
builder Flutter
给我们提供了四种构造ListView
的方法,有ListView()
、ListView.builder()
、ListView.separated()
、ListView.custom()
、
构造函数
描述
ListView()
静态构造方法 初始化之前需要确定数据源的大小
ListView.builder()
动态构造方法 可动态传入数据
ListView.separated()
动态构造方法 可动态传入数据 可动态定制分割线的样式
ListView.custom()
动态构造方法 需要传入SliverChildDelegate
来做动态生成
静态构造方法和动态构造方法 ListView()
是初始化的时候需要确定数据源的大小,一旦初始化成功后不能再次动态的插入数据。ListView.builder()
、ListView.separated()
、ListView.custom()
可以动态的插入数据,且能够更小的节省内存空间。 我们来看以下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 Flexible( child: ListView( children: List .generate( 10 , (index) { print ("without builder index = $index " ); return Container( height: 60 , child: Card( color: Colors.blue, child: Center(child: Text("$index " )), ), ); }, ), ), ), Flexible( child: ListView.builder( itemCount: 10 , itemExtent: 60 , itemBuilder: (BuildContext contenxt, int index) { print ("builder index = $index " ); return Container( height: 60 , child: Card( color: Colors.red, child: Center(child: Text("$index " )), ), ); }, ), ),
同样是需要初始化10个子控件,我们分别在List.generate
方法和itemBuilder
方法中做了打印操作 输出如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 flutter: without builder index = 0 flutter: without builder index = 1 flutter: without builder index = 2 flutter: without builder index = 3 flutter: without builder index = 4 flutter: without builder index = 5 flutter: without builder index = 6 flutter: without builder index = 7 flutter: without builder index = 8 flutter: without builder index = 9 flutter: builder index = 0 flutter: builder index = 1 flutter: builder index = 2 flutter: builder index = 3 flutter: builder index = 4 flutter: builder index = 5 flutter: builder index = 6 flutter: builder index = 7
由输出的log可见,builder
方法只初始化了7个子控件,ListView()
方法完整的初始化了10个子控件。builder
方法是在需要使用的时候 才会初始化,当页面滚动到第9个子控件的时候,这个时候才会初始化第9个子控件。 这样做的优势是:当我们的列表数据量很大的时候(比如说有成百上千个数据),我们只初始化几个来满足页面的显示需求,其他的控件在需要的时候,再做初始化这样就大大的帮助我们节省内存空间。
ListView
同时具备了水平布局和垂直布局的能力,我们只需要给scrollDirection
设置不同的参数即可。scrollDirection
接收的参数值有两个Axis.vertical
和Axis.horizontal
Axis.vertical 效果如下
Axis.horizontal 效果如下
reverse 参数reverse
可以控制列表是按正序显示还是倒序显示。
reverse = true 表示倒序显示
reverse = false 表示正序显示
physics 某些情况下我们并不想要ListView
可以滚动,只要把physics
设置为NeverScrollableScrollPhysics
即可。physics
还有其他两个比较重要的值:ClampingScrollPhysics
:在Android设备上有微光效果。BouncingScrollPhysics
:在iOS设备上有弹性效果。
separated 在ListView.separated()
构造函数中,我们可以传入一个自定义的Divider
来作作为分隔的样式 这里我们来看一下Divider
都有哪些参数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 const Divider({ Key key, this .height, this .thickness, this .indent, this .endIndent, this .color, })
height = 0
height = 10
thinkness = 10
indent = 100
end = 100
想体验以上示例的运行效果,可以到我的Github仓库 项目flutter_app
->lib
->routes
->listview_page.dart
查看,并且可以下载下来运行并体验。