flutter ListView列表 和 GridView网格

607 阅读2分钟

flutter 种常用的排版方式,ListView 和 GridView,可以看到下面是两个排版的最简单的区别。简单看一下它们的使用方式。

1672040467784.png

ListView 是列表, ListTile是常用的list 的item的widget

ListView 的常用属性
名称类型说明
scrollDirectionAxisAxis.horizontal水平列表Axis.vertical垂直列表
paddingEdgeInsetsGeometry内边距
resolvebool组件反向排序
childrenList列表元素
ListTile 的常用属性
名称类型说明
leadingWidget放在title前的widget,例如姓名前的icon图标,图文列表的图片
titleWidget元素的标题
subtitleWidget小标题,其位置在title的下面
trailingWidget放在title后面的的widget,例如姓名前的icon图标,图文列表的图片
ListView(
  children: <Widget>[
     ListTile(
       leading: Image.network("https://img0.baidu.com/it/u=823872589,3855820635&fm=253"),
       title: const Text('华北黄淮高温雨今起强势登场'),
       subtitle: const Text("中国天气网讯 21日开始,华北黄淮高温雨今起强势登场"),
     ),
     const Divider(),
  ],
)

ListView的动态列表

  1. 借助循环for ,或者其它的方式向 List 中添加widget,
class MyHomePage extends StatelessWidget {
  const MyHomePage({Key? key}) : super(key: key);
  List<Widget> _initListView() { // 私有方法,向list中添加10个listtile 
    List<Widget> list = [];
    for (var i = 0; i < 10; i++) { 
      list.add(const ListTile(
        title: Text("我是一个列表"),
      ));
    }
    return list;
  }

  @override
  Widget build(BuildContext context) {
    return ListView(
      children: _initListView(),// 调用私有方法
    );
  }
}
  1. 使用ListView.builder 方法实现
class MyHomePage extends StatelessWidget {
  List list = []; // widget list
  MyHomePage({Key? key}) : super(key: key) {
    for (var i = 0; i < 10; i++) { // 向list中添加10个字符串
      list.add("我是一个列表--$i");
    }
  }
  @override
  Widget build(BuildContext context) {
    return ListView.builder(
        itemCount: list.length, // 元素个数,必传
        itemBuilder: (context, index) { // context上下文,index下标
          return ListTile( // 返回一个widget
            title: Text("${list[index]}"),
          );
        });
  }
}

GridView网格

GridView 的常用属性
名称类型说明
scrollDirectionAxisAxis.horizontal水平列表Axis.vertical垂直列表
paddingEdgeInsetsGeometry内边距
resolvebool组件反向排序
childrenList列表元素
crossAxisSpacingdouble水平子元素之间的间距
mainAxisSpacingdouble垂直子元素之间的间距
crossAxisCountint一行有几个子元素,用在GridView.count 命名构造函数里面
maxCrossAxisExtentdouble子元素的最大长度,用在GridView.count 命名构造函数里面
childAspectRatiodouble子widget的宽高比
gridDelegateSliverGridDelegateWithFixedCrossAxisCount,SliverGridDelegateWithMaxCrossAxisExtent控制布局主要用在GridView.builder里面

GridView.count 实现网格布局

GridView.count构造函数内部使用了SliverGridDelegateWithFixedCrossAxisCount,我们通过它可以 快速的创建横轴固定数量子元素的GridView

1672042907780.png

class HomePage extends StatelessWidget {
  const HomePage({Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return GridView.count(
      crossAxisCount: 3, // 水平子元素数量
      childAspectRatio: 1.0, // 宽高比
      children: const <Widget>[ // 子元素
        Icon(Icons.home),
        Icon(Icons.ac_unit),
        Icon(Icons.search),
        Icon(Icons.settings),
        Icon(Icons.airport_shuttle),
        Icon(Icons.all_inclusive),
        Icon(Icons.beach_access),
        Icon(Icons.cake),
        Icon(Icons.circle),
      ],
    );
  }
}

GridView.extent实现网格布局

GridView.extent构造函数内部使用了SliverGridDelegateWithMaxCrossAxisExtent,我们通过它可以 快速的创建横轴子元素为固定最大长度的的GridView。

1672042940886.png

class HomePage extends StatelessWidget {
  const HomePage({Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return GridView.extent(
      maxCrossAxisExtent: 80.0, // 最大宽度
      childAspectRatio: 1.0, // 宽高比
      children: const <Widget>[ // 子元素
        Icon(Icons.home),
        Icon(Icons.ac_unit),
        Icon(Icons.search),
        Icon(Icons.settings),
        Icon(Icons.airport_shuttle),
        Icon(Icons.all_inclusive),
        Icon(Icons.beach_access),
        Icon(Icons.cake),
        Icon(Icons.circle),
      ],
    );
  }
}

GridView 动态列表

  1. SliverGridDelegateWithFixedCrossAxisCount, 它就相当于是GridView.count的
class HomePage extends StatelessWidget {
  final List listData = [ // 子元素内容list    {      'title': 'windy shop',      'sub': 'windy',      'image': 'https://img0.baidu.com/it/u=823872589,3855820635&fm=253'    },  ];
  HomePage({Key? key}) : super(key: key);
  Widget _getListData(context, index) {
    return Container(
      decoration: BoxDecoration(
          border: Border.all(
              color: const Color.fromRGBO(233, 233, 233, 0.9), width: 1)),
      child: Column(
        children: <Widget>[
          Image.network(listData[index]['imageUrl']),
          const SizedBox(height: 12),
          Text(
            listData[index]['title'],
            textAlign: TextAlign.center,
            style: const TextStyle(fontSize: 20),
          )
        ],
      ),
// height: 400, //设置高度没有反应
    );
  }

  @override
  Widget build(BuildContext context) {
    return GridView.builder(
//注意
      gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
        crossAxisSpacing: 10.0, //水平子 Widget 之间间距
        mainAxisSpacing: 10.0, //垂直子 Widget 之间间距
        crossAxisCount: 2, //一行的 Widget 数量
      ),
      itemCount: listData.length,
      itemBuilder: _getListData,
    );
  }
}

  1. SliverGridDelegateWithMaxCrossAxisExtent 它就相当于GridView.extent
GridView.builder(
//注意
gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent (
  crossAxisSpacing:10, // 水平子 Widget 之间间距
  mainAxisSpacing:10,//垂直子 Widget 之间间距
  maxCrossAxisExtent: 300,//子元素最大宽度
),
  itemCount: listData.length,
  itemBuilder: _getListData,
);