Flutter GridView

今天,我们来聊聊网格布局GridView。


GridView

构造数据(生成Widgets)


List<String> getDataList() {
    List<String> list = [];
    for (int i = 0; i < 100; i++) {
      list.add(i.toString());
    }
    return list;
  }

  List<Widget> getWidgetList() {
    return getDataList().map((item) => getItemContainer(item)).toList();
  }

  Widget getItemContainer(String item) {
    return Container(
      alignment: Alignment.center,
      child: Text(
        item,
        style: TextStyle(color: Colors.white, fontSize: 20),
      ),
      color: Colors.blue,
    );
  }

GridView有好几种写法,万变不离其宗。我们一个个来看看。

写法一:GridView.count


GridView.count(
      //水平子Widget之间间距
      crossAxisSpacing: 10.0,
      //垂直子Widget之间间距
      mainAxisSpacing: 30.0,
      //GridView内边距
      padding: EdgeInsets.all(10.0),
      //一行的Widget数量
      crossAxisCount: 2,
      //子Widget宽高比例
      childAspectRatio: 2.0,
      //子Widget列表
      children: getWidgetList(),
    );

效果:


GridView.count.gif

对于这种写法,此时单个Widget的宽高已经不起作用了。
在我上面构造数据的那一步中,我并没有指定Container的的宽高,这里我们就将其宽高设置为5,看下效果。


Widget getItemContainer(String item) {
    return Container(
      width: 5.0,
      height: 5.0,
      alignment: Alignment.center,
      child: Text(
        item,
        style: TextStyle(color: Colors.white, fontSize: 20),
      ),
      color: Colors.blue,
    );
  }

指定Container 宽高

可以看出没有效果。因为,我们在这里已经指定了每一行分成几列以及宽高比,还有边距等等。所以,我们后面再指定单个item的宽高,已经无效。

其实GridView跟我之前讲过的ListView,基本类似,都是BoxScrollView的子类。

GridView与ListView比较

GridView与ListView比较

写法二:GridView.builder


 @override
  Widget build(BuildContext context) {
    List<String> datas = getDataList();
    return GridView.builder(
        itemCount: datas.length,
        //SliverGridDelegateWithFixedCrossAxisCount 构建一个横轴固定数量Widget
        gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
          //横轴元素个数
            crossAxisCount: 3,
            //纵轴间距
            mainAxisSpacing: 20.0,
            //横轴间距
            crossAxisSpacing: 10.0,
            //子组件宽高长度比例
            childAspectRatio: 1.0),
        itemBuilder: (BuildContext context, int index) {
          //Widget Function(BuildContext context, int index)
          return getItemContainer(datas[index]);
        });
  }

abstract class SliverGridDelegate gridDelegate用来指定GridView的构建方式,具体实现有两个。

SliverGridDelegate

刚才这里例子,使用的SliverGridDelegateWithFixedCrossAxisCount。下面,我们来使用它的另一个实现SliverGridDelegateWithMaxCrossAxisExtent

写法三:GridView.builder(SliverGridDelegateWithMaxCrossAxisExtent)


GridView.builder(
      itemCount: datas.length,
      itemBuilder: (BuildContext context, int index) {
        return getItemContainer(datas[index]);
      },
      gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
        //单个子Widget的水平最大宽度
        maxCrossAxisExtent: 200,
        //水平单个子Widget之间间距
        mainAxisSpacing: 20.0,
        //垂直单个子Widget之间间距
        crossAxisSpacing: 10.0
      ),
    );

对于SliverGridDelegateWithMaxCrossAxisExtent而言,水平方向元素个数不再固定,其水平个数也就是有几列,由maxCrossAxisExtent和屏幕的宽度以及paddingmainAxisSpacing等决定。

例如:我这里的虚拟机宽度为400,当maxCrossAxisExtent:50时,有8列;当maxCrossAxisExtent:100时,有4列。如下:

maxCrossAxisExtent 效果
内容 内容
maxCrossAxisExtent:50
image.png
maxCrossAxisExtent:100
image.png

写法四:


@override
  Widget build(BuildContext context) {
    List<String> datas = getDataList();
    return GridView.custom(
        gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
            crossAxisCount: 3, mainAxisSpacing: 10.0, crossAxisSpacing: 20.0, ),
        childrenDelegate: SliverChildBuilderDelegate((context, position) {
          return getItemContainer(datas[position]);
        }, childCount: datas.length));
  }
GridView.custom.gif

这几个参数,上面都讲过了,不再赘述了。

本文代码地址

Flutter 豆瓣客户端,诚心开源
Flutter Container
Flutter SafeArea
Flutter Row Column MainAxisAlignment Expanded
Flutter Image全解析
Flutter 常用按钮总结
Flutter ListView豆瓣电影排行榜
Flutter Card
Flutter Navigator&Router(导航与路由)
OverscrollNotification不起效果引起的Flutter感悟分享
Flutter 上拉抽屉实现
Flutter 豆瓣客户端,诚心开源
Flutter 更改状态栏颜色

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • GridView 是一个网格布局的列组件。GridView 继承至 CustomScrollView,有 Cust...
    iwakevin阅读 5,580评论 1 2
  • ¥开启¥ 【iAPP实现进入界面执行逐一显】 〖2017-08-25 15:22:14〗 《//首先开一个线程,因...
    小菜c阅读 6,509评论 0 17
  • 问答题47 /72 常见浏览器兼容性问题与解决方案? 参考答案 (1)浏览器兼容问题一:不同浏览器的标签默认的外补...
    _Yfling阅读 13,790评论 1 92
  • 第一部分 HTML&CSS整理答案 1. 什么是HTML5? 答:HTML5是最新的HTML标准。 注意:讲述HT...
    kismetajun阅读 27,627评论 1 45
  • 7宝宝们陆陆续续的来到了塔塔班,开启在塔塔班一天的美好时光。 妞妞很安静地坐在苹苹老师腿上,让苹苹老师给自己扎头发...
    RYB塔塔班2阅读 204评论 0 0