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,
            ),
          ],
        ),
      ),
    );
  }
}
相关推荐
农夫三拳_有点甜5 小时前
Dart Lock类来自synchronized包
dart
农夫三拳_有点甜7 小时前
Dart 并发编程详细总结1
dart
星秋Eliot12 小时前
认识 Flutter
flutter
农夫三拳_有点甜12 小时前
Dart 运算符和操作符详细总结
dart
农夫三拳_有点甜12 小时前
Dart Timer 全面总结指南
dart
农夫三拳_有点甜12 小时前
Dart Class API 详细总结
dart
tangweiguo0305198712 小时前
Flutter 根据后台配置动态生成页面完全指南
flutter
stringwu12 小时前
Flutter开发者必备:状态管理Bloc的实用详解
前端·flutter
humiaor1 天前
Flutter之riverpod状态管理详解
flutter·provider·riverpod
浮生若茶80881 天前
创建Flutter项目的两种方式
flutter