Flutter控件——常用控件:ListView
Posted wzj_what_why_how
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Flutter控件——常用控件:ListView相关的知识,希望对你有一定的参考价值。
ListView
scroll_view.dart 源码
ListView(
Key? key,
Axis scrollDirection = Axis.vertical, // 滚动方向:横/纵(默认)
bool reverse = false, // 决定滚动方向是否与阅读方向一致,true 表示不一样,显示时是列表直接滚动到最底下,最后一个 item 显示第一个数据
ScrollController? controller, // 主要作用是控制滚动位置和监听滚动事件
// primary: 当内容不足以滚动时,是否支持滚动;对于ios系统还有一个效果:当用户点击状态栏时是否滑动到顶部。这个挺重要的,
//尤其是使用列表构建页面时配合下拉刷新,要是数据量小于屏幕高度的话,这个就管用了。此时系统会自动给 listview 设置
//一个默认的滚动控制器 PrimaryScrollController,好处是父组件可以控制子树中可滚动组件的滚动行为
bool? primary,
ScrollPhysics? physics, //
bool shrinkWrap = false, // 是否根据子组件的总长度来设置 ListView 的长度,默认值为 false,所以能滚动。滚动组件相互嵌套时,shrinkWrap 属性要设置 true 才行,和 NeverScrollableScrollPhysics 配合就能解决滚动冲突
EdgeInsetsGeometry? padding, //
this.itemExtent, // 可以直接设置列表项高度,可以提高列表性能
this.prototypeItem, //
//addAutomaticKeepAlives - 该属性表示是否将列表项(子组件)包裹在AutomaticKeepAlive组件中,在一个懒加载列表中,
//如果将列表项包裹在AutomaticKeepAlive中,在该列表项滑出视口时也不会被回收,它会使用KeepAliveNotification来保
//存其状态。如果列表项自己维护其KeepAlive状态,那么此参数必须置为false
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, //
String? restorationId, //
Clip clipBehavior = Clip.hardEdge, //
)
四种构建方式
4种构建方式,也就是有4个构造方法。核心思路就是把生成 item 的部分看成一个对象函数(各种build) 传进构造方法中。
build 设计模式,都是包装成 build。
第一种:静态列表。把固定数据变成 item 传给 childen (ps:一般要将ListView抽出来一个类去放,然后再使用,酱紫不会导致代码视觉上嵌套太多层)
ListView(
padding: EdgeInsets.all(20),
children: <Widget>[
Text("AA"),
Text("BB"),
Text("CC"),
],
);
ListView(
padding: EdgeInsets.all(20),
children: <Widget>[
ListTile(
leading: Icon(Icons.ac_unit),
title: Text("这个列表子项"),
),
ListTile(
leading: Icon(Icons.ac_unit),
title: Text("这个列表子项"),
),
ListTile(
leading: Icon(Icons.ac_unit),
title: Text("这个列表子项"),
),
],
);
ListView(
Image.network(
'https://profile.csdnimg.cn/8/9/E/0_wzj_what_why_how',
width: 200,
height: 200,
),
Container(
width: 200,
height: 200,
color: Colors.purple,
),
Image.network(
'https://profile.csdnimg.cn/8/9/E/0_wzj_what_why_how',
width: 200,
height: 200,
),
],
);
第二种:动态列表 ListView.builder()
List类型的使用
List是Dart的集合类型之一,其实你可以把它简单理解为数组(反正我是这么认为的),其他语言也都有这个类型。它的声明有几种方式:
var myList = List(): 非固定长度的声明。
var myList = List(2): 固定长度的声明。
var myList= List<String>():固定类型的声明方式。
var myList = [1,2,3]: 对List直接赋值。
eg: 构建50个子项的List:
//generate方法传递两个参数,第一个参数是生成的个数,第二个是方法。
items = List<String>.generate(50, (index) => "这是选项:$index")
ListView.builder - 构建一种 item 类型的列表 (在 itemBuilder 使用 if、slse 也是能支持多类型 item 的)
new ListView.builder(
itemCount: items.length, //列表数量
itemBuilder: (context, index)
return new ListTile(title: new Text('$items[index]')); //子项控件
)
第三种: ListView.separated - 带分割线的列表 (separatorBuilder:在这个参数中构建分割线)
ListView.separated(
padding: EdgeInsets.all(20),
itemCount: 50,
itemBuilder: (context, index)
return Text("item:$index");
,
//扩展:可以根据 index 找到前后 item 的类型,然后考虑可以采取不同类型的分隔 item
separatorBuilder: (context,index)
return Container(
height: 1,
color: Colors.pink,
);
,
);
第四种:ListView.custom()
需要传入一个实现了 SliverChildDelegate 的组件,如 SliverChildListDelegate 和 SliverChildBuilderDelegate。
SliverChildListDelegate 就是 listview,SliverChildBuilderDelegate 就是 ListView.builder。
这个 ListView.custom 用的也比较少。
参数–scrollController 滚动控制 : 主要功能就是监听滚动状态,提供方法滚动到列表指定位置
可以设置选择列表从哪里开始显示,配合 itemExtent 每列固定高度设置是个不错的思路。
scroll_controller.dart源码:
ScrollController(
double initialScrollOffset = 0.0,//初始滚动位置
this.keepScrollOffset = true, //是否保存滚动位置
this.debugLabel,
)
scrollController 的核心参数、方法:
- offset - 当前滚动到的位置,注意这个数据是累计值,不是每次滚动的量
- jumpTo(double offset) - 滚动到指定位置,不带动画。目前只能滚动到指定 px
- animateTo(double offset,…) - 滚动到指定位置,带动画,可以指定时间
scrollController 可以添加多个 Listener 呢的,从其方法 scrollController.addListener 就能看的出来,走进源码中 _listeners 是一个集合类型
NotificationListener 滚动监听
android 中有 NestedScrollingParent、NestedScrollingChild 这一对接口,NestedScrollingChild 发送滚动事件,NestedScrollingParent 控制滚动事件的传播和数值。
Flutter 继承这一思路。在 widget 树中,可滚动 widget 滚动时会逐次向上传递滚动事件 notification,我们可以通过NotificationListener 可以监控到该 notification,NotificationListener 也是一个 widget,只要NotificationListener 的布局层级比 listview 高就行,隔几层都没关系,一样可以监听的到。
只要是 Flutter 中的滚动 widget,如:ScrollView、ListView、PageView 等都能使用 NotificationListener 监听滚动事件。
监听方法:
NotificationListener 中 onNotification(ScrollNotification notification) 方法可以拿到滚动事件,数值包裹在 ScrollNotification 这个参数中。需要我们返回一个 boolean 值:
true - 那么 notification 到此为止,我们拦截了滚动事件,不会继续上传滚动事件,但是不影响 listview 自身 widget 的滚动
false - 那 么notification 会继续向更外层 widget 传递。
……
ListTile
内部列表。不仅可以使用在ListView组件中,然后容器组件其实都可以使用。
参考:Flutter - Listview 详解:https://juejin.cn/post/6844904019475824648
以上是关于Flutter控件——常用控件:ListView的主要内容,如果未能解决你的问题,请参考以下文章