第五章:Scrollable Widgets(四) --GridView

Flutter-从入门到放弃(源码,目录,持续更新中)

学习了ListView的使用之后,我们继续学习另外一种非常常用的列表Widget-GridView。
GridView可以在水平和竖直方向上排列子Widget,并在这两个方向进行滑动:
在这里插入图片描述

构造器

类似ListView,GridView继承自 ScrollView,它们的构造器也很类似。GridView有五种构造器:

  • 默认构造器,直接声明其包含的widget列表
  • GridView.builder()
  • GridView.count()
  • GridView.custom()
  • GridView.extent()

其中 builder() 和 count() 构造器是最常用的两个,类似ListView的构造器。
下面是一些需要注意的参数:

  • crossAxisSpacing:交叉的轴上的子widget之间的间距
  • mainAxisSpacing:主轴上的子widget之间的间距
  • crossAxisCount:交叉轴上的子widget的数量,即每行上的widget的数量,也是列的数量
  • shrinkWrap:控制固定的滚动区域的大小
  • physics:控制 scroll view 对用户输入的响应方式
  • primary:告诉Flutter哪个scroll view 是主要的那个,在 ListView 中我们已经用过了
  • scrollDirection:控制滚动的方向

cross axis 和 main axis

main axis 并不是固定的,而是对应于滚动的方向,比如水平方向滚动时,类似于Row
在这里插入图片描述
竖直方向滚动时,类似于Column
在这里插入图片描述

Grid delegates

Grid delegates 用来帮助我们确定排列GridView中的widget时的间距和列数。除了自定义Grid delegates外,Fultter为我们提供了两个预定义好的Grid delegates:

  • SliverGridDelegateWithFixedCrossAxisCount
  • SliverGridDelegateWithMaxCrossAxisExtent
    顾名思义,第一个会在cross axis上设置固定的item,而第二个将会在cross axis上设置尽可能多的item。

创建Recipes页面

现在我们准备使用 GridView 来创建 Recipes 页面,打开 screens 目录,创建 recipes_screen.dart,添加如下代码:

import 'package:flutter/material.dart';

import '../api/mock_fooderlich_service.dart';
import '../models/simple_recipe.dart';

class RecipesScreen extends StatelessWidget {
  //模拟获取数据
  final exploreService = MockFooderlichService();

  RecipesScreen({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
      future: exploreService.getRecipes(),
      builder: (context, AsyncSnapshot<List<SimpleRecipe>> snapshot) {
        //判断是否已经获取到数据
        if (snapshot.connectionState == ConnectionState.done) {
          // TODO: Add RecipesGridView Here
          //暂时添加一个文本在这里
          return const Center(child: Text('Recipes Screen'));
        } else {
          //未获取到数据时展示一个加载框
          return const Center(child: CircularProgressIndicator());
        }
      },
    );
  }
}

进入home.dart,导入新建的文件:

import 'screens/recipes_screen.dart';

home.dart 中找到TODO: Replace with RecipesScreen,将其替换为RecipesScreen

RecipesScreen(),

这个页面类似 ExploreScreen,我们暂时只在里面添加了一个加载框和文本,效果如下:
在这里插入图片描述

创建菜谱缩略图

在创建GridView之前,我们需要先把其中的item创建好,也就是菜谱缩略图,效果如下:
在这里插入图片描述
缩略图很简单,展示了菜谱的图片,名称以及烹饪时间。
lib/components 文件夹里,创建 recipe_thumbnail.dart,添加如下代码:

import 'package:flutter/material.dart';

import '../models/models.dart';

class RecipeThumbnail extends StatelessWidget {
  //菜谱的数据
  final SimpleRecipe recipe;

  const RecipeThumbnail({
    Key? key,
    required this.recipe,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    //创建一个Container作为整体容器,padding为8
    return Container(
      padding: const EdgeInsets.all(8),
      //Column进行垂直方向的布局
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          //图片的包装Widget
          Expanded(
            //创建一个圆角图片
            child: ClipRRect(
              child: Image.asset(
                '${recipe.dishImage}',
                fit: BoxFit.cover,
              ),
              borderRadius: BorderRadius.circular(12),
            ),
          ),
          //图片与文本之间设置一个间隔
          const SizedBox(height: 10),
          //菜谱的名称展示
          Text(
            recipe.title,
            maxLines: 1,
            style: Theme.of(context).textTheme.bodyText1,
          ),
          //菜谱的烹饪时间
          Text(
            recipe.duration,
            style: Theme.of(context).textTheme.bodyText1,
          )
        ],
      ),
    );
  }
}

components.dart 中导入该文件

export 'recipe_thumbnail.dart';

接下来就可以创建 GridView了。

创建GridView

lib/components 里创建 recipes_grid_view.dart,添加如下代码:

import 'package:flutter/material.dart';

import '../components/components.dart';
import '../models/models.dart';

class RecipesGridView extends StatelessWidget {
  //菜谱数据的列表
  final List<SimpleRecipe> recipes;

  const RecipesGridView({
    Key? key,
    required this.recipes,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    //在左右和上方设置16的padding
    return Padding(
      padding: const EdgeInsets.only(
        left: 16,
        right: 16,
        top: 16,
      ),
      //通过builder()方法构造GridView
      child: GridView.builder(
        //item的数量
        itemCount: recipes.length,
        //使用Flutter预定义的gridDelegate,在cross axis方向上的item数量设置为2
        gridDelegate:
            const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
        itemBuilder: (context, index) {
          //通过数据创建item
          final simpleRecipe = recipes[index];
          return RecipeThumbnail(recipe: simpleRecipe);
        },
      ),
    );
  }
}

打开 components.dart,导入该文件:

export 'recipes_grid_view.dart';

打开 recipes_screen.dart,在注释TODO: Add RecipesGridView Here下方替换为以下代码:

return RecipesGridView(recipes: snapshot.data ?? []);

运行APP,就可以看到GridView的效果了。

在这里插入图片描述
GridView 的学习就到这里了,下一节我们稍微介绍一下其他 Scroll View

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值