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

同样实现了这样的功能。

相关推荐
莹雨潇潇5 分钟前
Docker 快速入门(Ubuntu版)
java·前端·docker·容器
Jiaberrr13 分钟前
Element UI教程:如何将Radio单选框的圆框改为方框
前端·javascript·vue.js·ui·elementui
Tiffany_Ho1 小时前
【TypeScript】知识点梳理(三)
前端·typescript
安冬的码畜日常2 小时前
【D3.js in Action 3 精译_029】3.5 给 D3 条形图加注图表标签(上)
开发语言·前端·javascript·信息可视化·数据可视化·d3.js
小白学习日记3 小时前
【复习】HTML常用标签<table>
前端·html
早起的年轻人3 小时前
Flutter String 按 ,。分割
flutter
丁总学Java3 小时前
微信小程序-npm支持-如何使用npm包
前端·微信小程序·npm·node.js
yanlele3 小时前
前瞻 - 盘点 ES2025 已经定稿的语法规范
前端·javascript·代码规范
懒羊羊大王呀3 小时前
CSS——属性值计算
前端·css