• flutter中 ListView的使用


    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'),
          ),
        ]);
      }
    }
    

    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官网上查到安装及使用步骤,这里我就不累述太多'),
          ),
        ]);
      }
    }
    

    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官网上查到安装及使用步骤,这里我就不累述太多'),
          ),
        ]);
      }
    }
    

    6.垂直列表

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

    7.水平排列

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

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

    作者:流年少年
    出处:https://www.cnblogs.com/ishoulgodo/

    想问问题,打赏了卑微的博主,求求你备注一下的扣扣或者微信;这样我好联系你;(っ•̀ω•́)っ✎⁾⁾!

    如果觉得这篇文章对你有小小的帮助的话,记得在右下角点个“推荐”哦,或者关注博主,在此感谢!

    万水千山总是情,打赏5毛买辣条行不行,所以如果你心情还比较高兴,也是可以扫码打赏博主(っ•̀ω•́)っ✎⁾⁾!

    想问问题,打赏了卑微的博主,求求你备注一下的扣扣或者微信;这样我好联系你;(っ•̀ω•́)っ✎⁾⁾!

    支付宝
    微信
    本文版权归作者所有,欢迎转载,未经作者同意须保留此段声明,在文章页面明显位置给出原文连接
    如果文中有什么错误,欢迎指出。以免更多的人被误导。
  • 相关阅读:
    JSP的组成
    什么是JSP
    JSP和Servlet分工图
    Linux逻辑卷管理LVM2详解
    ESXi主机和NTP server快速进行时间同步
    VMwareCLI命令参考
    使用Logminer工具分析DML和DDL操作
    TKPROF使用
    iSCSI存储设备的udev绑定 以及iscsi重启卡住解决方法
    Oracle 10g EM证书问题
  • 原文地址:https://www.cnblogs.com/ishoulgodo/p/14993174.html
Copyright © 2020-2023  润新知