Flutter(四):SingleChildScrollView、GridView

SingleChildScrollView、GridView 遇到的问题

以下代码会报错:

dart 复制代码
class GridViewPage extends StatefulWidget {
  const GridViewPage({super.key});

  @override
  State<GridViewPage> createState() => _GridViewPage();
}

class _GridViewPage extends State<GridViewPage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('GridView 布局')),
      body: SingleChildScrollView(
        child: GridView.count(
          crossAxisCount: 1,
          children: [
            Container(color: Colors.red),
            Container(color: Colors.green),
            Container(color: Colors.blue),
            Container(color: Colors.black),
            Container(color: Colors.grey),
          ],
        ),
      ),
    );
  }
}

修改方案一

存在问题:给定一个高度的方法虽然能解决报错问题,但是滚动区域会固定在所给高度内,无法自适应高度

dart 复制代码
class GridViewPage extends StatefulWidget {
  const GridViewPage({super.key});

  @override
  State<GridViewPage> createState() => _GridViewPage();
}

class _GridViewPage extends State<GridViewPage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('GridView 布局')),
      body: SizedBox(
        height: 500,
        child: GridView.count(
          crossAxisCount: 1,
          children: [
            Container(color: Colors.red),
            Container(color: Colors.green),
            Container(color: Colors.blue),
            Container(color: Colors.black),
            Container(color: Colors.grey),
          ],
        ),
      ),
    );
  }
}

修改方案二

存在问题:页面不能滚动

shrinkWrap: true: 自适应GridView高度

dart 复制代码
class GridViewPage extends StatefulWidget {
  const GridViewPage({super.key});

  @override
  State<GridViewPage> createState() => _GridViewPage();
}

class _GridViewPage extends State<GridViewPage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('GridView 布局')),
      body: SingleChildScrollView(
        child: GridView.count(
          crossAxisCount: 1,
          shrinkWrap: true,
          children: [
            Container(color: Colors.red),
            Container(color: Colors.green),
            Container(color: Colors.blue),
            Container(color: Colors.black),
            Container(color: Colors.grey),
          ],
        ),
      ),
    );
  }
}

解决页面不能滚动问题

physics: const NeverScrollableScrollPhysics(): 禁用GridView自带的滚动

dart 复制代码
class GridViewPage extends StatefulWidget {
  const GridViewPage({super.key});

  @override
  State<GridViewPage> createState() => _GridViewPage();
}

class _GridViewPage extends State<GridViewPage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('GridView 布局')),
      body: SingleChildScrollView(
        child: GridView.count(
          crossAxisCount: 1,
          shrinkWrap: true,
          physics: const NeverScrollableScrollPhysics(),
          children: [
            Container(color: Colors.red),
            Container(color: Colors.green),
            Container(color: Colors.blue),
            Container(color: Colors.black),
            Container(color: Colors.grey),
          ],
        ),
      ),
    );
  }
}

实现 GridView 布局

属性 描述
shrinkWrap 自适应宽高
scrollDirection 布局方向
childAspectRatio 主轴、交叉轴 比
mainAxisSpacing 主轴间距
crossAxisSpacing 交叉轴间距
crossAxisCount 交叉轴列数
maxCrossAxisExtent 交叉轴列最尺寸
dart 复制代码
import 'package:flutter/material.dart';

class TitleWidget extends StatelessWidget {
  final String title;

  const TitleWidget(this.title, {super.key});

  @override
  Widget build(BuildContext context) {
    return Container(
      margin: const EdgeInsets.fromLTRB(10, 5, 10, 5),
      padding: const EdgeInsets.only(left: 5),
      decoration: const BoxDecoration(
        border: Border(left: BorderSide(color: Colors.lightBlue, width: 5)),
      ),
      child: Text(title),
    );
  }
}

class ContainerWidget extends StatelessWidget {
  final Color color;
  final String title;

  const ContainerWidget({super.key, required this.color, required this.title});

  @override
  Widget build(BuildContext context) {
    return Container(
      decoration: BoxDecoration(
        color: color,
        borderRadius: const BorderRadius.all(Radius.circular(5)),
      ),
      child: Center(child: Text(title)),
    );
  }
}

class GridViewPage extends StatefulWidget {
  const GridViewPage({super.key});

  @override
  State<GridViewPage> createState() => _GridViewPage();
}

class _GridViewPage extends State<GridViewPage> {
  List<ContainerWidget> containerWidgetList = const [
    ContainerWidget(color: Colors.red, title: 'RED'),
    ContainerWidget(color: Colors.orange, title: 'ORANGE'),
    ContainerWidget(color: Colors.yellow, title: 'YELLOW'),
    ContainerWidget(color: Colors.green, title: 'GREEN'),
    ContainerWidget(color: Colors.cyan, title: 'CYAN'),
    ContainerWidget(color: Colors.blue, title: 'BLUE'),
    ContainerWidget(color: Colors.purple, title: 'PURPLE'),
    ContainerWidget(color: Colors.grey, title: 'GREY'),
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('GridView 布局')),
      body: SingleChildScrollView(
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            const TitleWidget('GridView.count'),
            SizedBox(
              height: 160,
              child: GridView.count(
                scrollDirection: Axis.horizontal,
                crossAxisCount: 1,
                padding: const EdgeInsets.only(left: 10, right: 10),
                crossAxisSpacing: 0,
                mainAxisSpacing: 10,
                childAspectRatio: 0.6,
                children: containerWidgetList,
              ),
            ),
            const TitleWidget('GridView.extent'),
            GridView.extent(
              shrinkWrap: true,
              physics: const NeverScrollableScrollPhysics(),
              scrollDirection: Axis.vertical,
              maxCrossAxisExtent: 200,
              childAspectRatio: 0.8,
              padding: const EdgeInsets.only(left: 10, right: 10),
              mainAxisSpacing: 10,
              crossAxisSpacing: 10,
              children: containerWidgetList,
            ),
            const TitleWidget('SliverGridDelegateWithFixedCrossAxisCount'),
            SizedBox(
              height: 330,
              child: GridView(
                gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
                  crossAxisCount: 2,
                  crossAxisSpacing: 10,
                  mainAxisSpacing: 10,
                  childAspectRatio: 0.6,
                ),
                scrollDirection: Axis.horizontal,
                padding: const EdgeInsets.only(left: 10, right: 10),
                children: containerWidgetList,
              ),
            ),
            const TitleWidget('SliverGridDelegateWithMaxCrossAxisExtent'),
            GridView(
              gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(
                maxCrossAxisExtent: 200,
                childAspectRatio: 2,
                mainAxisSpacing: 10,
                crossAxisSpacing: 10,
              ),
              shrinkWrap: true,
              physics: const NeverScrollableScrollPhysics(),
              scrollDirection: Axis.vertical,
              padding: const EdgeInsets.only(left: 10, right: 10, bottom: 10),
              children: containerWidgetList,
            ),
          ],
        ),
      ),
    );
  }
}
相关推荐
一只大侠的侠32 分钟前
Flutter开源鸿蒙跨平台训练营 Day 3
flutter·开源·harmonyos
一只大侠的侠2 小时前
【Harmonyos】Flutter开源鸿蒙跨平台训练营 Day 2 鸿蒙跨平台开发环境搭建与工程实践
flutter·开源·harmonyos
微祎_3 小时前
Flutter for OpenHarmony:构建一个 Flutter 平衡球游戏,深入解析动画控制器、实时物理模拟与手势驱动交互
flutter·游戏·交互
ZH15455891314 小时前
Flutter for OpenHarmony Python学习助手实战:面向对象编程实战的实现
python·学习·flutter
renke33644 小时前
Flutter for OpenHarmony:构建一个 Flutter 色彩调和师游戏,RGB 空间探索、感知色差计算与视觉认知训练的工程实现
flutter·游戏
王码码20355 小时前
Flutter for OpenHarmony 实战之基础组件:第三十一篇 Chip 系列组件 — 灵活的标签化交互
android·flutter·交互·harmonyos
ujainu6 小时前
Flutter + OpenHarmony 实现经典打砖块游戏开发实战—— 物理反弹、碰撞检测与关卡系统
flutter·游戏·openharmony·arkanoid·breakout
微祎_6 小时前
构建一个 Flutter 点击速度测试器:深入解析实时交互、性能度量与响应式 UI 设计
flutter·ui·交互
王码码20356 小时前
Flutter for OpenHarmony 实战之基础组件:第二十七篇 BottomSheet — 动态底部弹窗与底部栏菜单
android·flutter·harmonyos
ZH15455891317 小时前
Flutter for OpenHarmony Python学习助手实战:Web开发框架应用的实现
python·学习·flutter