Flutter--List列表组件

列表布局是我们项目开发中最常用的一种布局方式。Flutter中我们可以通过ListView来定义列表项,支持垂直和水平方向展示。通过一个属性就可以控制列表的显示方向。列表有如下分类:

(1)垂直列表

(2)垂直图文列表

(3)水平列表

(4)动态列表

列表组件的常用参数: (1) scrollDirection Axis Axis.horizontal表示水平列表,Axis.vertical垂直列表 (2) padding EdgeInsetsGeometry 内边距 (3) resolve bool 组件反向排序 (4) children List 列表元素

1.垂直列表

(1)最简单的实现

less 复制代码
class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return ListView(
      children: const [
        ListTile(
          title: Text('我是一个列表'),
        ),
        Divider(),
        ListTile(
          title: Text('我是一个列表'),
        ),
        Divider(),
        ListTile(
          title: Text('我是一个列表'),
        ),
        Divider(),
        ListTile(
          title: Text('我是一个列表'),
        ),
        Divider(),
        ListTile(
          title: Text('我是一个列表'),
        ),
        Divider(),
        ListTile(
          title: Text('我是一个列表'),
        ),
        Divider(),
        ListTile(
          title: Text('我是一个列表'),
        ),
        Divider(),
        ListTile(
          title: Text('我是一个列表'),
        ),
        Divider(),
        ListTile(
          title: Text('我是一个列表'),
        ),
        Divider(),
        ListTile(
          title: Text('我是一个列表'),
        ),
      ],
    );
  }
}

使用ListTile可以配合ListView快速实现垂直列表的效果。

(2)带图标的垂直列表

less 复制代码
class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return ListView(
      children: const [
        ListTile(
          leading: Icon(Icons.home,color: Colors.blue,),
          title: Text('首页'),
          trailing: Icon(Icons.chevron_right_sharp),
        ),
        Divider(),
        ListTile(
          leading: Icon(Icons.assessment,color: Colors.orange,),
          title: Text('订单'),
          trailing: Icon(Icons.chevron_right_sharp),
        ),
        Divider(),
      ],
    );
  }
}

这里,我们可以通过leading和trailing分别设置左侧和最右侧的图标。

2.垂直图文列表

(1)新闻列表

less 复制代码
class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return ListView(
      padding: const EdgeInsets.fromLTRB(0,10, 0, 0),
      children: [
        ListTile(
          leading: Image.network('https://www.itying.com/images/flutter/1.png'),
          title: const Text('这是一个新闻标题'),
          subtitle: const Text('副标题'),
        ),
        const Divider(),
        ListTile(
          leading: Image.network('https://www.itying.com/images/flutter/2.png'),
          title: const Text('这是一个新闻标题'),
        ),
        const Divider(),
        ListTile(
          leading: Image.network('https://www.itying.com/images/flutter/3.png'),
          title: const Text('这是一个新闻标题'),
        ),
        const Divider(),
        ListTile(
          leading: Image.network('https://www.itying.com/images/flutter/4.png'),
          title: const Text('这是一个新闻标题'),
        ),
      ],
    );
  }
}

如图,这样我们就可以实现简单实现一个图文列表。

(2)图片列表 我们不仅仅可以使用上述的ListTile实现图片列表,使用Image和Text也是可以实现图文列表的。

less 复制代码
class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return ListView(
      padding: const EdgeInsets.fromLTRB(0, 10, 0, 0),
      children: [
        Image.network('https://www.itying.com/images/flutter/1.png'),
        Container(
          height: 44,
          padding: const EdgeInsets.fromLTRB(0, 10, 0, 0),
          child: const Text(
            '这是一个标题',
            style: TextStyle(fontSize: 22.0),
            textAlign: TextAlign.center,
          ),
        ),
        Image.network('https://www.itying.com/images/flutter/2.png'),
        Container(
          height: 44,
          padding: const EdgeInsets.fromLTRB(0, 10, 0, 0),
          child: const Text(
            '这是一个标题',
            style: TextStyle(fontSize: 22.0),
            textAlign: TextAlign.center,
          ),
        ),
        Image.network('https://www.itying.com/images/flutter/3.png'),
        Container(
          height: 44,
          padding: const EdgeInsets.fromLTRB(0, 10, 0, 0),
          child: const Text(
            '这是一个标题',
            style: TextStyle(fontSize: 22.0),
            textAlign: TextAlign.center,
          ),
        ),
        Image.network('https://www.itying.com/images/flutter/4.png'),
        Container(
          height: 44,
          padding: const EdgeInsets.fromLTRB(0, 10, 0, 0),
          child: const Text(
            '这是一个标题',
            style: TextStyle(fontSize: 22.0),
            textAlign: TextAlign.center,
          ),
        ),
      ],
    );
  }
}

3.水平列表

通过指定ListView的scrollDirection,我们可以实现水平滑动的列表:

less 复制代码
class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return SizedBox(
      height: 120,
      child: ListView(
        scrollDirection: Axis.horizontal,
        children: [
          Container(
            width: 120,
            decoration: const BoxDecoration(color: Colors.red),
            child: Column(
              children: [
                SizedBox(
                  height: 90,
                  child: Image.network('https://www.itying.com/images/flutter/1.png',fit: BoxFit.cover,),
                ),
                const Text('我是标题'),
              ],
            ),
          ),
          Container(
            width: 120,
            decoration: const BoxDecoration(color: Colors.green),
            child: Column(
              children: [
                SizedBox(
                  height: 90,
                  child: Image.network('https://www.itying.com/images/flutter/2.png',fit: BoxFit.cover,),
                ),
                const Text('我是标题'),
              ],
            ),
          ),
          Container(
            width: 120,
            decoration: const BoxDecoration(color: Colors.yellow),
            child: Column(
              children: [
                SizedBox(
                  height: 90,
                  child: Image.network('https://www.itying.com/images/flutter/3.png',fit: BoxFit.cover,),
                ),
                const Text('我是标题'),
              ],
            ),
          ),
          Container(
            width: 120,
            decoration: const BoxDecoration(color: Colors.pink),
            child: Column(
              children: [
                SizedBox(
                  height: 90,
                  child: Image.network('https://www.itying.com/images/flutter/4.png',fit: BoxFit.cover,),
                ),
                const Text('我是标题'),
              ],
            ),
          ),
          Container(
            width: 120,
            decoration: const BoxDecoration(color: Colors.blue),
            child: Column(
              children: [
                SizedBox(
                  height: 90,
                  child: Image.network('https://www.itying.com/images/flutter/5.png',fit: BoxFit.cover,),
                ),
                const Text('我是标题'),
              ],
            ),
          ),
        ],
      ),
    );
  }
}

需要注意的就是我们需要在ListView外层嵌套一层,以给ListView设置一个确切的高度。实现水平滑动总体来讲,还是算比较容易的。

4.动态列表

(1)定义一个方法,返回List,赋值给children。

scala 复制代码
class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  List<Widget> _initListData() {
    List<Widget> list = [];
    for(int i =0;i<20;i++) {
      list.add(ListTile(title: Text('数据:$i'),),);
    }
    return list;
  }

  @override
  Widget build(BuildContext context) {
    return ListView(
      children: _initListData(),
    );
  }
}

(2)渲染动态的数组数据

提供动态的数组数据

ini 复制代码
List dataList = [
  {
    "author": 'AA',
    "title": '这是一个副标题',
    "url": 'https://www.itying.com/images/flutter/1.png',
  },
  {
    "author": 'BB',
    "title": '这是一个副标题',
    "url": 'https://www.itying.com/images/flutter/2.png',
  },
  {
    "author": 'CC',
    "title": '这是一个副标题',
    "url": 'https://www.itying.com/images/flutter/3.png',
  }
];
ini 复制代码
import 'res/dataList.dart';
class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);
  
  List<Widget> _initListData() {
    List<Widget> list = [];
    for (int i = 0; i < dataList.length; i++) {
      list.add(
        ListTile(
          title: Text(dataList[i]['author']),
          subtitle: Text(dataList[i]['title']),
          leading: Image.network(dataList[i]['url']),
        ),
      );
    }
    return list;
  }

  @override
  Widget build(BuildContext context) {
    return ListView(
      children: _initListData(),
    );
  }
}

上述的我们也可以通过map变换操作来实现:

scss 复制代码
class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  List<Widget> _initListData() {
    return dataList
        .map((value) => ListTile(
              title: Text(value['author']),
              subtitle: Text(value['author']),
              leading: Image.network(value['url']),
            ))
        .toList();
  }

  @override
  Widget build(BuildContext context) {
    return ListView(
      children: _initListData(),
    );
  }
}

(3)使用List.builder动态渲染数据

这里还是使用了上述提供的动态数组数据

scala 复制代码
class MyApp extends StatelessWidget {
 const MyApp({Key? key}) : super(key: key);

 @override
 Widget build(BuildContext context) {
   return ListView.builder(
       itemCount: dataList.length, itemBuilder: (context, i) {
     return ListTile(
       title: Text(dataList[i]['author']),
       subtitle: Text(dataList[i]['title']),
       leading: Image.network(dataList[i]['url']),
     );
   });
 }
}

同样实现了这样的功能。

相关推荐
mldong43 分钟前
你的 Vue3 项目也能有钉钉同款审批流设计器:npm 装包,10 分钟画出第一条审批流
前端·vue.js
2分钟速写快排1 小时前
什么是 RAG?如何用 RAG 实现一个用户记忆?
前端·后端·ai编程
passerby60612 小时前
如何自己造一个时间处理库
前端·javascript·github
走到天涯海角3 小时前
react里面的长列表渲染优化
前端·react.js·前端框架
小羊没烦恼!3 小时前
Hello Web API系列教程——Web API与国际化
java·服务器·前端·javascript·php
北岛贰3 小时前
迷茫焦虑期,我做了一个带支付带官网的 AI 聊天虚拟恋人 App
前端·人工智能·后端
mayaairi5 小时前
Vue2 组件通讯(三):全局事件总线、PubSub、插槽与组件实例属性
前端·javascript·vue.js
kyriewen6 小时前
面试官问我:AI 都能写代码了,前端凭什么还值 25K
前端·javascript·人工智能
风骏时光牛马6 小时前
AI源码分析:拆解模型底层实现逻辑
前端
IT_陈寒7 小时前
React子组件莫名其妙重渲染?你可能漏了这个Hook
前端·人工智能·后端