flutter中ListView的详细讲解

  • A+
所属分类:Web前端

1.ListView的简单介绍

ListView是最常用的可以滚动组件之一, 它可以沿一个方向进行线性排列所有的子组件。 下面是ListView的属性值介绍:  scrollDirection:列表的滚动方向, 可选值有Axis的horizontal和vertical, 默认是垂直方向上滚动。  controller:控制器,与列表滚动相关,比如监听列表的滚动事件。  physics: 列表滚动至边缘后继续拖动的物理效果, Android与iOS效果不同。 Android会呈现出一个波纹状(对应ClampingScrollPhysics), 而iOS上有一个回弹的弹性效果(对应BouncingScrollPhysics)。 如果你想不同的平台上呈现各自的效果可以使用AlwaysScrollableScrollPhysics, 它会根据不同平台自动选用各自的物理效果。如果你想禁用在边缘的拖动效果, 那可以使用NeverScrollableScrollPhysics;  shrinkWrap: 该属性将决定列表的长度是否仅包裹其内容的长度。 当ListView嵌在一个无限长的容器组件中时, shrinkWrap必须为true,否则Flutter会给出警告;  padding: 列表内边距;  itemExtent: 子元素长度。 当列表中的每一项长度是固定的情况下可以指定该值, 有助于提高列表的性能 (因为它可以帮助ListView在未实际渲染子元素之前就计算出每一项元素的位置);  children: 容纳子元素的组件数组。 

2.ListTile 属性简介

this.leading,              // 内容的==>前置图标 this.title,                // 内容的==>标题 this.subtitle,             // 内容的==>副标题 this.trailing,             // 内容的==>后置图标 this.isThreeLine = false,  // 内容的==>是否三行显示 this.dense,                // 内容的==>直观感受是整体大小 this.contentPadding,       // 内容的==>内容内边距 this.enabled = true,       // 内容 是否禁用 this.onTap,                // item onTap 点击事件 this.onLongPress,          // item onLongPress 长按事件 this.selected = false,     // item 是否选中状态 

3.ListView的基本使用

我们做一个新闻列表; 结构非常的简单:有主标题和副标题 title(主标题)和subtitle(subtitle) 我们一起来看看长成什么样子。 
class MyCont extends StatelessWidget {   @override   Widget build(BuildContext context) {     return ListView(children: <Widget>[       ListTile(         // 主标题         title: Text('Flutter 由 Google 的工程师团队打造,用于创建高性能、跨平台的移动应用',             //文字左对齐             textAlign: TextAlign.left,              //超出显示省略号             overflow: TextOverflow.ellipsis,              style: TextStyle(               //数字必须是Double类型的               fontSize: 20.0,                //  设置字体的颜色               color: Color.fromARGB(200, 100, 100, 8)             )         ),         // 副标题         subtitle: Text('你好flutter'),       ),       ListTile(         title: Text('Flutter 由 Google 的工程师团队打造,用于创建高性能、跨平台的移动应用'),         subtitle: Text('你好flutter'),       ),     ]);   } } 

flutter中ListView的详细讲解

4.listView列表设置前置图标

class MyCont extends StatelessWidget {   @override   Widget build(BuildContext context) {     return ListView(children: <Widget>[       ListTile(         // 主标题         // 在前面设置图标         leading: Icon(           //设置图标类型           Icons.settings,            //0x后面开始 两位FF表示透明度16进制,           color: Color(0xFFFFB6C1),            //这是图标的大小           size: 30.0         ),         // 在后面设置图标         // trailing: Icon(Icons.accessible),         title: Text('flutter教程_2021 Dart Flutter入门实战视频教程132讲',           //文字左对齐           textAlign: TextAlign.left,            //超出显示省略号           overflow: TextOverflow.ellipsis,            style: TextStyle(             fontSize: 20.0, //数字必须是Double类型的             //  设置字体的颜色             color: Color(0xFFFFB6C1)           )         ),         subtitle: Text('不管是Ios还是Android开发都可以在flutter官网上查到安装及使用步骤,这里我就不累述太多'),       ),     ]);   } } 

flutter中ListView的详细讲解

5.设置前置图片

class MyCont extends StatelessWidget {   @override   Widget build(BuildContext context) {     return ListView(children: <Widget>[       ListTile(         // 主标题         // 通过leading可以将图片放在前面         leading: Image.network(           "https://giidu.c/ster/src=http%3A%2F%2Ft14.npg"),           title: Text(             'flutter教程_2021 Dart Flutter入门实战视频教程132讲',             textAlign: TextAlign.left, //文字左对齐             overflow: TextOverflow.ellipsis, //超出显示省略号             style: TextStyle(               fontSize: 20.0, //数字必须是Double类型的               //  设置字体的颜色               color: Color(0xFFFFB6C1)             )           ),         subtitle: Text('不管是Ios还是Android开发都可以在flutter官网上查到安装及使用步骤,这里我就不累述太多'),       ),     ]);   } } 

flutter中ListView的详细讲解

6.垂直列表

class MyCont extends StatelessWidget {   @override   Widget build(BuildContext context) {     return ListView(children: <Widget>[       Container(         width: 750.0,         height: 200.0,         color:Color(0xFFFFB6C1),         // 外边距 左上右下,跟css不一样哈         margin: EdgeInsets.fromLTRB(10, 10, 10, 0),       ),       Container(         width: 750.0,         height: 200.0,         color: Color(0xFFFFB6C1),         // 外边距 左上右下,跟css不一样哈         margin: EdgeInsets.fromLTRB(10, 10, 10, 0),       )     ]);   } } 

flutter中ListView的详细讲解

7.水平排列

class MyCont extends StatelessWidget {   @override   Widget build(BuildContext context) {     return Container(       height: 200.0,       child:new ListView(         // 水平排列          scrollDirection: Axis.horizontal, children: <Widget>[           Container(             width: 220.0,             height: 200.0,             color: Color(0xFFFFB6C1),             // 外边距 左上右下,跟css不一样哈             margin: EdgeInsets.fromLTRB(10, 10, 10, 0),           ),           Container(             width: 220.0,             height: 200.0,             color: Color(0xFFFFB6C1),             // 外边距 左上右下,跟css不一样哈             margin: EdgeInsets.fromLTRB(10, 10, 10, 0),           ),           Container(             width: 220.0,             height: 200.0,             color: Color(0xFFFFB6C1),             // 外边距 左上右下,跟css不一样哈             margin: EdgeInsets.fromLTRB(10, 10, 10, 0),           ),         ]       )     );   } } 

flutter中ListView的详细讲解

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());   } } 

flutter中ListView的详细讲解

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());   } } 

flutter中ListView的详细讲解