SingleChildScrollView、GridView 遇到的问题
以下代码会报错:
class GridViewPage extends StatefulWidget {
const GridViewPage({super.key});
State<GridViewPage> createState() => _GridViewPage();
}
class _GridViewPage extends State<GridViewPage> {
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),
],
),
),
);
}
}
修改方案一
存在问题:给定一个高度的方法虽然能解决报错问题,但是滚动区域会固定在所给高度内,无法自适应高度
class GridViewPage extends StatefulWidget {
const GridViewPage({super.key});
State<GridViewPage> createState() => _GridViewPage();
}
class _GridViewPage extends State<GridViewPage> {
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高度
class GridViewPage extends StatefulWidget {
const GridViewPage({super.key});
State<GridViewPage> createState() => _GridViewPage();
}
class _GridViewPage extends State<GridViewPage> {
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自带的滚动
class GridViewPage extends StatefulWidget {
const GridViewPage({super.key});
State<GridViewPage> createState() => _GridViewPage();
}
class _GridViewPage extends State<GridViewPage> {
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 | 交叉轴列最尺寸 |
import 'package:flutter/material.dart';
class TitleWidget extends StatelessWidget {
final String title;
const TitleWidget(this.title, {super.key});
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});
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});
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'),
];
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,
),
],
),
),
);
}
}