Flutter--GridView组件

43 阅读2分钟

GridView网格布局在实际项目中用的也是非常多的,当我们想让可以滚动的元素使用矩阵方式排列的时候,此时我们可以用网格列表组件GridView实现布局。

GridView创建网格布局主要有下面三种方式

(1)可以通过GridView.count实现网格布局

(2)可以通过GridView.extent实现网格布局

(3)通过GridView.builder实现动态网格布局

常用属性有:

(1) scrollDirection Axis 滚动反向

(2) padding EdgeInsetsGeometry 内边距

(3) resolve bool 组件反向排序

(4) crossAxisSpacing double 水平子Widget之间间距

(5) mainAxisSpacing double 垂直子Widget之间间距

(6) crossAxisCount int用在GridView.count 一行的Widget数量

(7) maxCrossAxisExtent double用在GridView.extent 横轴子元素的最大长度

(8) childAspectRatio double 子Widget宽高比例

(9) children []

(10) gridDelegate SliverDelegateWithFixedCrossAxisCount&&SliverDelegateWithMaxCrossAxisExtent 控制布局主要用在GridView.builder里面

1.GridView.count的简单用法

class Demo1 extends StatelessWidget {
  const Demo1({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return GridView.count(
      crossAxisCount: 5,
      children: const [
        Icon(Icons.home),
        Icon(Icons.search),
        Icon(Icons.assessment),
        Icon(Icons.home),
        Icon(Icons.search),
        Icon(Icons.assessment),
        Icon(Icons.home),
        Icon(Icons.search),
        Icon(Icons.assessment),
      ],
    );
  }
}

image.png

2.GridView.extent的简单用法

class Demo2 extends StatelessWidget {
  const Demo2({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return GridView.extent(
      maxCrossAxisExtent: 120,
      children: const [
        Icon(Icons.home),
        Icon(Icons.search),
        Icon(Icons.assessment),
        Icon(Icons.home),
        Icon(Icons.search),
        Icon(Icons.assessment),
        Icon(Icons.home),
        Icon(Icons.search),
        Icon(Icons.assessment),
      ],
    );
  }
}

image.png maxCrossAxisExtent设置的值不同,呈现出来的效果也可能会不同。

3.crossAxisSpacing和mainAxisSpacing、childAspectRatio的使用

class Demo3 extends StatelessWidget {
  const Demo3({Key? key}) : super(key: key);

  List<Widget> _initGridView() {
    List<Widget> tempList = [];
    for (int i = 0; i < 12; i++) {
      tempList.add(Container(
        alignment: Alignment.center,
        decoration: const BoxDecoration(
          color: Colors.blue,
        ),
        child: Text(
          'item:${i}',
          style: const TextStyle(fontSize: 20, color: Colors.white),
        ),
      ));
    }
    return tempList;
  }

  @override
  Widget build(BuildContext context) {
    return GridView.count(
      crossAxisCount: 2,
      //水平widget之间的距离
      crossAxisSpacing: 10,
      //垂直widget之间的距离
      mainAxisSpacing: 10,
      //宽高比
      childAspectRatio: 1.2,
      //宽高比
      children: _initGridView(),
    );
  }
}

image.png

Widget之间有了间隙,宽高比也是会根据childAspectRatio设置的值来的

如果是Grid.extent则这样使用:

class Demo4 extends StatelessWidget {
  const Demo4({Key? key}) : super(key: key);

  List<Widget> _initGridView() {
    List<Widget> tempList = [];
    for (int i = 0; i < 12; i++) {
      tempList.add(Container(
        alignment: Alignment.center,
        decoration: const BoxDecoration(
          color: Colors.blue,
        ),
        child: Text(
          'item:$i',
          style: const TextStyle(fontSize: 20, color: Colors.white),
        ),
      ));
    }
    return tempList;
  }

  @override
  Widget build(BuildContext context) {
    return GridView.extent(
      maxCrossAxisExtent: 180,
      crossAxisSpacing: 10,
      //水平widget之间的距离
      mainAxisSpacing: 10,
      //垂直widget之间的距离
      childAspectRatio: 1.2,
      //宽高比
      children: _initGridView(),
    );
  }
}

4.GridView.count实现动态数组渲染

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',
  }
];
class Demo5 extends StatelessWidget {
  const Demo5({Key? key}) : super(key: key);

  List<Widget> _initGridView() {
    return dataList.map((e) {
      return Container(
        decoration: BoxDecoration(
          border: Border.all(color: Colors.black26),
        ),
        child: Column(
          children: [
            Image.network(e['url']),
            const SizedBox(
              height: 10,
            ),
            Text(
              e['author'],
              style: const TextStyle(fontSize: 18),
            ),
          ],
        ),
      );
    }).toList();
  }

  @override
  Widget build(BuildContext context) {
    return GridView.count(
      padding: EdgeInsets.all(10),
      crossAxisCount: 2,
      crossAxisSpacing: 10,
      //水平widget之间的距离
      mainAxisSpacing: 10,
      //垂直widget之间的距离
      childAspectRatio: 1,
      //宽高比
      children: _initGridView(),
    );
  }
}

image.png

5.GridView.builder实现动态列表

(1)SliverGridDelegateWithFixedCrossAxisCount

class Demo6 extends StatelessWidget {
  const Demo6({Key? key}) : super(key: key);

  Widget _initGridView(context, index) {
    return Container(
      decoration: BoxDecoration(
        border: Border.all(color: Colors.black26),
      ),
      child: Column(
        children: [
          Image.network(dataList[index]['url']),
          const SizedBox(
            height: 10,
          ),
          Text(
            dataList[index]['author'],
            style: const TextStyle(fontSize: 18),
          ),
        ],
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return GridView.builder(
      padding: const EdgeInsets.all(10),
      itemCount: dataList.length,
      gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
        crossAxisCount: 2,
        mainAxisSpacing: 10,
        crossAxisSpacing: 10,
        childAspectRatio: 1,
      ),
      itemBuilder: _initGridView,
    );
  }
}

(2) SliverGridDelegateWithMaxCrossAxisExtent

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  Widget _initGridView(context, index) {
    return Container(
      decoration: BoxDecoration(
        border: Border.all(color: Colors.black26),
      ),
      child: Column(
        children: [
          Image.network(dataList[index]['url']),
          const SizedBox(
            height: 10,
          ),
          Text(
            dataList[index]['author'],
            style: const TextStyle(fontSize: 18),
          ),
        ],
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return GridView.builder(
      padding: const EdgeInsets.all(10),
      itemCount: dataList.length,
      gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(
        maxCrossAxisExtent: 200,
        mainAxisSpacing: 10,
        crossAxisSpacing: 10,
        childAspectRatio: 1,
      ),
      itemBuilder: _initGridView,
    );
  }
}

实现的效果和上述示意图一样。

至此GridView的简单用法就一一演示了一遍。