Flutter 学习笔记(三) 列表

223 阅读3分钟

列表

列表布局通过 ListView 来定义列表项,支持垂直和水平方向展示。通过一个属性就可以控制列表的显示方向。
列表有以下分类:

  1. 垂直列表
  2. 垂直图文列表
  3. 水平列表
  4. 动态列表
  5. 矩阵式列表

Flutter 列表参数

名称类型说明
scrollDirectionAxisAxis.horizontal 水平列表 Axis.vertical 垂直列表
paddingEdgeInsetsGeometry内边距
resolvebool组件反向排序
childrenList列表元素

新闻列表布局

垂直列表

class HomeContent extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ListView(
      padding: EdgeInsets.all(10),
      children: <Widget>[
        ListTile(
            leading: Icon(Icons.access_alarm, color: Colors.red, size: 40), //前添加icon图标及修改颜色和大小
            title:
                Text("谈判在即 美国官员首次透露计划对俄制裁细节", style: TextStyle(fontSize: 20)),
            subtitle: Text("关于拜登icon想要借乌克兰问题和俄罗斯做交易、牺牲乌克兰换取俄罗斯在中美的问题上帮助美国的事情,早就已经是公开的秘密。")
        ),
        ListTile(
          title: Text("谈判在即 美国官员首次透露计划对俄制裁细节"),
          subtitle: Text("关于拜登icon想要借乌克兰问题和俄罗斯做交易、牺牲乌克兰换取俄罗斯在中美的问题上帮助美国的事情,早就已经是公开的秘密。"),
          trailing: Icon(Icons.home),//后添加icon图标
        ),
        ListTile(
            leading: Image.asset("images/1.jpg"), // 前添加图片
            title: Text("谈判在即 美国官员首次透露计划对俄制裁细节"),
            subtitle: Text("关于拜登icon想要借乌克兰问题和俄罗斯做交易、牺牲乌克兰换取俄罗斯在中美的问题上帮助美国的事情,早就已经是公开的秘密。")
        ),
      ],
    );
  }
}

垂直图文列表

class HomeContent extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ListView(padding: EdgeInsets.all(10), children: <Widget>[
      Image.asset("images/1.jpg"),
      Container(
          child: Text(
            'hello wolrd',
            textAlign: TextAlign.center,
            style: TextStyle(
              fontSize: 28,
            ),
          ),
          height: 60,
          padding: EdgeInsets.fromLTRB(0, 10, 0, 10)
      ),
      Image.asset("images/2.jpg"),
      Image.asset("images/1.jpg"),
      Image.asset("images/2.jpg"),
    ]);
  }
}

水平列表

class HomeContent extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
        height: 180,
        child: ListView(
          scrollDirection: Axis.horizontal, // 修改列表的方向
          children: <Widget>[
              Container(width: 180.0, color: Colors.red),
              Container(width: 180.0, color: Colors.blue),
              Container(
                  width: 180.0,
                  color: Colors.yellow,
                  child: ListView(children: <Widget>[
                    Image.asset("images/1.jpg"),
                    Text("hello world")
                  ])),
              Container(width: 180.0, color: Colors.green),
              Container(width: 180.0, color: Colors.orange),
        ]));
  }
}

动态列表

map 方法进行循环遍历

import 'res/listData.dart'; // 引入本地数据

class HomeContent extends StatelessWidget {
  List<Widget> _getData() {
    var tempList = listData.map((value) {
      return ListTile(
        leading: Image.network(value["imageUrl"]),
        title: Text(value["title"]),
        subtitle: Text(value["author"], style: TextStyle(color: Colors.blue)),
      );
    });

    return tempList.toList();
  }

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

ListView.builder 的方法进行循环遍历

import 'res/listData.dart'; // 引入本地数据

class HomeContent extends StatelessWidget {
  List list = [];

  @override
  Widget build(BuildContext context) {
    return ListView.builder(
      itemCount: listData.length,
      itemBuilder: (context, index) {
        return ListTile(
            leading: Image.network(listData[index]["imageUrl"]),
            title: Text(listData[index]["title"]),
            subtitle: Text(listData[index]["author"],
                style: TextStyle(color: Colors.blue)));
      },
    );
  }
}

商品列表布局

GridView 组件

GridView 创建网格列表有多种方式,下面我们主要介绍两种:1. 可以通过 GridView.count 实现网格布局 2. 通过 GridView.builder 实现网格布局

常用属性:

名称类型说明
scrollDirectionAxisAxis.horizontal 水平列表 Axis.vertical 垂直列表
paddingEdgeInsetsGeometry内边距
resolvebool组件反向排序
childrenList列表元素
crossAxisSpacingdouble水平子 Widget 之间间距
mainAxisSpacingdouble垂直子 Widget 之间间距
crossAxisCountint一行的 Widget 数量
childAspectRatiodouble子 Widget 宽高比例
gridDelegateSliverGridDelegateWithFix edCrossAxisCount(常用) SliverGridDelegateWithMax CrossAxisExtent控制布局主要用在 GridView.builder 里面

GridView.count

模拟动态组件渲染

class HomeContent extends StatelessWidget {
  List<Widget> _getData() {
    List<Widget> list = [];

    for (var i = 0; i < 20; i++) {
      list.add(Container(
          alignment: Alignment.center,
          child: Text("hello world",
              style: TextStyle(
                color: Colors.yellow,
              )),
          color: Colors.green));
    }

    return list;
  }

  @override
  Widget build(BuildContext context) {
    return GridView.count(
      crossAxisCount: 3, //- 网格布局显示的列数
      padding: EdgeInsets.all(10),
      crossAxisSpacing: 10.0, //- 列之间的距离
      mainAxisSpacing: 20.0, //- 水平之间的距离
      childAspectRatio: 2, //- 宽高的比例
      children: this._getData(),
    );
  }
}
//- 效果入下图所示

image.png

本地数据渲染

class HomeContent extends StatelessWidget {
  List<Widget> _getData() {
    var tempList = listData.map((value) {
      return Container(
          child: Column(children: <Widget>[
            Image.network(value['imageUrl']),
            SizedBox(height: 15), //- 用来调整图片和文字间的距离
            Text(value['title'], style: TextStyle(color: Colors.red)),
          ]),
          decoration: BoxDecoration(
              border: Border.all(color: Colors.blue, width: 3.0)));
    });

    return tempList.toList();
  }

  @override
  Widget build(BuildContext context) {
    return GridView.count(
      crossAxisCount: 2, //- 网格布局显示的列数
      padding: EdgeInsets.all(10),
      crossAxisSpacing: 10.0, //- 列之间的距离
      mainAxisSpacing: 20.0, //- 水平之间的距离
      // childAspectRatio: 2, //- 宽高的比例
      children: this._getData(),
    );
  }
}

//- 效果如下图所示

image.png

GridView.builder

class HomeContent extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return GridView.builder(
        //- gridDelegate 必填参数
        gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
          crossAxisCount: 2, //- 网格布局显示的列数
          crossAxisSpacing: 10.0, //- 列之间的距离
          mainAxisSpacing: 20.0, //- 水平之间的距离
          // childAspectRatio: 2, //- 宽高的比例
        ),
        itemCount: listData.length,
        itemBuilder: (context, index) {
          return Container(
              child: Column(children: <Widget>[
                Image.network(listData[index]['imageUrl']),
                SizedBox(height: 15), //- 用来调整图片和文字间的距离
                Text(listData[index]['title'],
                    style: TextStyle(color: Colors.orange)),
              ]),
              decoration: BoxDecoration(
                  border: Border.all(color: Colors.blue, width: 3.0)));
        });
  }
}