8.动态列表
在项目的实际开发过程中;
我们会有很多的列表;
我们想将ListView中children中的代码封装成为一个函数。
方便后期的管理
class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold(appBar: AppBar(title: Text('首页')), body: MyCont()), //设置顶部的颜色 theme: ThemeData(primarySwatch: Colors.yellow), ); } } class MyCont extends StatelessWidget { // Lis里面的数据必须是Widget组件; // _backDataList方法下划线开头,表示当前这个类私有的。 List<Widget> _backDataList() { return [ ListTile( title: Text('我是新闻标题1'), ), ListTile( title: Text('我是新闻标题2'), ), ListTile( title: Text('我是新闻标题3'), ), ListTile( title: Text('我是新闻标题4'), ) ]; } @override Widget build(BuildContext context) { return ListView(children: this._backDataList()); } }
9.往数组中添加数据进行循环
class MyCont extends StatelessWidget { // Lis里面的数据必须是Widget组件; // _backDataList方法下划线开头,表示当前这个类私有的。 List<Widget>_backDataList() { // 声明了一个数组,里面的数据类型是Widget List<Widget> list = []; for (var i = 0; i < 10; i++) { list.add(ListTile( title: Text('我是新闻标题$i'), )); } return list; } @override Widget build(BuildContext context) { return ListView(children: this._backDataList()); } }
10.为什么要使用ListView.builder
ListView.builder下的两个属性值 itemCount:指定被循环数组的长度 itemBuilder:它有2个参数。 itemBuilder(contText, index) { contText表示的循环的内容 index表示循环的索引值 }
如果itemBuilder下是一个封装的函数,
不要添加括号,因为括号表示调用;
直接itemBuilder:this.youFunc就可以了
使用ListView.builder的优势:
ListView.builder适合列表项比较多(或者无限)的情况,
只有当子组件真正显示的时候列表才会被创建,
也就说通过该构造函数创建的ListView是支持基于Sliver的懒加载模型的。
也就是说使用ListView.builder可以提升性能。
下面我们将会使用ListView.builder来创建一个列表
在lib目录下创建一个res
在res目录下创建demo.dart
demo.dart文件下有数据的哈
import 'res/demo.dart'; List listData = [ { 'title': 'Python 创作季,秀出你的 Python 文章 } ]
后面使用listData就可以直接获取数据了哈
class MyCont extends StatelessWidget { @override Widget build(BuildContext context) { return ListView.builder( // itemCount:指定该数组的长度 itemCount: listData.length, //itemBuilder 会进行循环遍历 itemBuilder: (contText, index) { return ListTile( title: Text(listData[index]['title']), //还有很多的属性xxxx........ ); }, ); } }
前面我们说了,使用ListView.builder可以提高性能;
但是我们发现了itemBuilder下如果有很多属性的话;
那么就会变得非常的臃肿的;
后期是不利于我们维护;
那么我们能不能将 itemBuilder中的抽离出去了?
经过我的查询文档发现是可以的
请看下面:
11.将itemBuilder中的属性抽离出去
我们可以将原来itemBuilder下的代码
封装成为一个方法放置在自定义的_getListData下;
方便我们后期的维护以及修改
class MyCont extends StatelessWidget { //自定义的方法 Widget _getListData(contText, index){ return ListTile( title: Text(listData[index]['title']), ); } @override Widget build(BuildContext context) { return ListView.builder( // itemCount:指定该数组的长度 itemCount: listData.length, //this._getListData是不需要加括号的; // 我们这里表示的复制该方法 // this._getListData()表示的是直接去调用这个方法 itemBuilder:this._getListData ); } }
12.ListView children与ListView.builder的区别
通过前面的例子,
我们可以发现ListView有默认构造函数。
ListView默认构造函数有一个children参数,
children接受一个Widget列表[List],
通过children参数的形式接受的子组件列表。
这种方式需要将所有的children都提前创建好;
因此需要提前做大量的工作;
所以:这种形式只适合少量的子组件的情况
ListView.builder
ListView.builder适合列表项比较多(或者无限)的情况,
只有当子组件真正显示的时候列表才会被创建,
也就说通过该构造函数创建的ListView是支持基于Sliver的懒加载模型的。
13.制作一个好看的列表
我们将使用后置图标trailing这个属性来完成图片后置。
同时我们将给一个容器组件Container;
容器组件的宽高来限制图片的大小;
我们将会对图片进行裁剪,
在lib目录下创建一个res
在res目录下创建demo.dart
demo.dart文件下有数据的哈
import 'res/demo.dart'; List listData = [ { 'title': 'Python 创作季,秀出你的 Python 文章 } ] class MyCont extends StatelessWidget { // Lis里面的数据必须是Widget组件; // _backDataList方法下划线开头,表示当前这个类私有的。 List<Widget> _backDataList() { var temtepleList = listData.map((value) { return ListTile( title: Text( value['title'], // 超出显示省略号 overflow: TextOverflow.ellipsis, style: TextStyle(fontSize: 16.0, color: Color(0xFF86909c)), ), subtitle: Text( value['cont'], overflow: TextOverflow.ellipsis, style: TextStyle(fontSize: 13.0, color: Color(0xFF86909c)), ), trailing: Container( width: 90.0, //容器宽 height: 70.0, //容器高 decoration: BoxDecoration( borderRadius: BorderRadius.circular(4.0), image: DecorationImage( image: NetworkImage( value['img'], ), alignment: Alignment.topLeft, //左上角居中 fit: BoxFit.cover, //裁剪,充满整个容器。不会变形 ) ) ) ); }); // 转化成为一个数组 return temtepleList.toList(); } @override Widget build(BuildContext context) { return ListView(children: this._backDataList()); } }