网站怎么办/全自动引流推广软件下载
文章目录
- Flutter ListView
- Flutter ListView加载更多/异步加载(ListView.builder)
- Flutter ListView分割线(ListView.separated)
Flutter ListView
列表布局在手机上是最最常用的控件了。
Android上的RecycleView尤其的强大。
Flutter中也给我们提供了ListView,不过就目前的体验来看,性能跟原生的ListView或RecycleView比还是有一点差距的。滑动起来还是略卡。
下面我们来看一下ListView的相关知识
继承关系
可以看到,ListView和GridView都继承自BoxScrollView,因此,他们的属性差不多,用法也相似。
构造方法
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.down,})
常用属性
属性 | 值类型 | 说明 |
---|---|---|
scrollDirection | Axis | 设置滚动的方向,horizontal(水平)或vertical(垂直) |
reverse | bool | 是否翻转 |
itemExtent | double | 滚动方向子控件的长度,垂直方向即为高度,水平方向即为宽度 |
controller | ScrollController | 用来控制滚动位置及监听滚动事件 |
shrinkWrap | bool | 是否根据子widget的总长度来设置ListView的长度 |
padding | EdgeInsetsGeometry | 间距 |
children | List | 子控件 |
常用属性都比较简单,没啥好说的,我们来直接用一下
ListView(children: List.generate(30, (index) {return Container(alignment: Alignment.center,decoration: BoxDecoration(border: Border.all(color: Colors.red),),child: Text("item${index}"),);}),);
效果图:
这里我们要注意一下itemExtent属性
itemExtent
该属性用来控制子控件在滚动方向上的长度,所以它跟scrollDirection是密切相关的。
例如:
当滚动方向为垂直方向时,那么itemExtent就是控制子控件的高度
当滚动方向为水平方向时,那么itemExtent就是控制子控件的宽度
示例:我们在垂直方向上设置一下itemExtent
ListView(scrollDirection: Axis.vertical,itemExtent: 60,children: List.generate(50, (index) {return Container(alignment: Alignment.center,decoration: BoxDecoration(border: Border.all(color: Colors.red),),child: Text("item${index}"),);}),);
图示如下:此时,itemExtent控制的是子控件的高度
我们更改一下滚动方向为水平:
ListView(scrollDirection: Axis.horizontal,itemExtent: 60,children: List.generate(50, (index) {return Container(alignment: Alignment.center,decoration: BoxDecoration(border: Border.all(color: Colors.red),),child: Text("item${index}"),);}),);
此时,itemExtent控制的就是子控件的宽度了
图示:
Flutter ListView加载更多/异步加载(ListView.builder)
构造方法适合在数据较少且固定的情况下使用,我们在开发过程中一般数据都是从网络获取的,并且基本都有分页的需求,此时,我们就需要动态的加载数据了。
跟GridView一样,ListView提供了ListView.builder方法供我们动态加载数据时使用,且使用方法基本一致。
首先看看源码:
ListView.builder({Key key,Axis scrollDirection = Axis.vertical,bool reverse = false,ScrollController controller,bool primary,ScrollPhysics physics,bool shrinkWrap = false,EdgeInsetsGeometry padding,this.itemExtent,@required IndexedWidgetBuilder itemBuilder,int itemCount,bool addAutomaticKeepAlives = true,bool addRepaintBoundaries = true,bool addSemanticIndexes = true,double cacheExtent,int semanticChildCount,DragStartBehavior dragStartBehavior = DragStartBehavior.down,})
属性跟构造方法中的属性差不多,我们主要来看看itemCount和itemBuilder
itemCount表示列表的数量,一般都是集合的长度
itemBuilder是列表项构造器,返回一个Widget
这里我就直接用了
import 'package:flutter/material.dart';/*
* 列表控件
*
* */
class ListViewWidget extends StatelessWidget {@overrideWidget build(BuildContext context) {return ListView(scrollDirection: Axis.horizontal,itemExtent: 60,children: List.generate(50, (index) {return Container(alignment: Alignment.center,decoration: BoxDecoration(border: Border.all(color: Colors.red),),child: Text("item${index}"),);}),);}
}class ListViewBuilder extends StatefulWidget {@overrideState<StatefulWidget> createState() {return _ListViewBuilder();}
}class _ListViewBuilder extends State<ListViewBuilder> {/*初始项为50个*/List<int> indexs = List.generate(50, (index) {return index;});@overrideWidget build(BuildContext context) {return ListView.builder(itemCount: indexs.length,itemBuilder: (context, index) {/*加载到底部时且集合数量小于100的话,获取更多数据*/if (index==indexs.length-1&&indexs.length < 100) {_getMoreData(index);}return Text("${index}");});}void _getMoreData(int index) {Future.delayed(Duration(milliseconds: 300)).then((e) {setState(() {/*往集合里添加10条数据*/indexs.addAll(List.generate(10, (i) {return index + i;}));});});}
}
图示:
初始值集合中只有50条数据,然后每次增加10条
Flutter ListView分割线(ListView.separated)
通常情况下,我们的列表之间都有分割线,便于用户区分,我们既可以在子控件中手动添加分割线的样式,例如一开始的构造方法那样,但是那样会造成分割线重叠的情况。
而ListView.separated可以让我们方便的给列表加上分割线。
我们先来看一下源码:
ListView.separated({Key key,Axis scrollDirection = Axis.vertical,bool reverse = false,ScrollController controller,bool primary,ScrollPhysics physics,bool shrinkWrap = false,EdgeInsetsGeometry padding,@required IndexedWidgetBuilder itemBuilder,@required IndexedWidgetBuilder separatorBuilder, //分割线@required int itemCount,bool addAutomaticKeepAlives = true,bool addRepaintBoundaries = true,bool addSemanticIndexes = true,double cacheExtent,})
可以看到属性中多了一个separatorBuilder
separatorBuilder即为分割线构建器
下面我们给上面的列表加上灰色分割线:
import 'package:flutter/material.dart';/*
* 列表控件
*
* */
class ListViewWidget extends StatelessWidget {@overrideWidget build(BuildContext context) {return ListView(scrollDirection: Axis.horizontal,itemExtent: 60,children: List.generate(50, (index) {return Container(alignment: Alignment.center,decoration: BoxDecoration(border: Border.all(color: Colors.red),),child: Text("item${index}"),);}),);}
}class ListViewBuilder extends StatefulWidget {@overrideState<StatefulWidget> createState() {return _ListViewBuilder();}
}class _ListViewBuilder extends State<ListViewBuilder> {/*初始项为50个*/List<int> indexs = List.generate(50, (index) {return index;});@overrideWidget build(BuildContext context) {/*灰色分割线*/var divider = Divider(color: Colors.grey,);return ListView.separated(padding: EdgeInsets.all(10),itemCount: indexs.length,separatorBuilder: (context, index) {return divider;},itemBuilder: (context, index) {/*加载到底部时且集合数量小于100的话,获取更多数据*/if (index == indexs.length - 1 && indexs.length < 100) {_getMoreData(index);}return Text("${index}");});}void _getMoreData(int index) {Future.delayed(Duration(milliseconds: 300)).then((e) {setState(() {/*往集合里添加10条数据*/indexs.addAll(List.generate(10, (i) {return index + i;}));});});}
}
好了 Flutter ListView的基本用法大概就是这样
如果你觉得本文对你有帮助,麻烦动动手指顶一下,算是对本文的一个认可。也可以关注我的 Flutter 博客专栏,我会不定期的更新,如果文中有什么错误的地方,还望指正,转载请注明转自喻志强的博客 ,谢谢!