Flutter之所以有这么多组件,是因为在适当的位置需要用适当的组件。此篇主要聊下GrideView。
想了解GrideView基础用法,请移步:flutterBookhttps://book.flutterchina.club/chapter6/gridview.html
最终要实现的布局截图:
先编写基础页面布局:
import 'package:flutter/material.dart';
void main(){
runApp(
MyApp()
);
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'GridView实战',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Container(
color: Colors.white,
width: double.infinity,
height: double.infinity,
),
);
}
}
细心地你一定注意到了一个代码块:
home: Container(
color: Colors.white,
width: double.infinity,
height: double.infinity,
)
为什么是width:double.infinity还有height: double.infinity。这是个编写技巧,实现的是一个宽高撑满界面(也就是宽高100%)的布局。
下面主角出场:
Container(
color: Colors.white,
width: double.infinity,
height: double.infinity,
child: GridView.count(
crossAxisCount: 5,
children: [
Column(
children: [
Icon(Icons.add),
Text("文字")
],
)
],
),
)
运行结果如下:
看界面报错提示应该是说超过了78px。
android studio报错信息如下:
那么 确诊是高度超出了,这个报错在flutter布局中大家应该是相当熟悉了吧。
试着修改字体来修复问题:
Column(
children: [
Icon(Icons.add),
Text(
"文字",
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.normal,
decoration: TextDecoration.none,
color: Colors.black
),
)
],
)
问题暂时解决了:
我想要让图标跟文字垂直水平居中:
GridView.count(
childAspectRatio: 1,
crossAxisCount: 5,
children: [
Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.add),
Text(
"文字",
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.normal,
decoration: TextDecoration.none,
color: Colors.black
),
)
],
),
)
],
这里向大家推荐良心好工具:DevTool(建议把谷歌浏览器设置成默认浏览器再开启)
实在是找不到布局问题在哪里或者说想看布局作用区间的就可以用上面的工具。
取消查看模拟器或者手机app布局格子,可以再次点击网页版DevTool的Select Widget Mode
继续刻画图标:
Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 40.0,
height: 40.0,
decoration: BoxDecoration(
color: Colors.blueAccent,
borderRadius: BorderRadius.circular(20.0)
),
child: Icon(
Icons.add,
color: Colors.white,
),
),
Text(
"文字",
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.normal,
decoration: TextDecoration.none,
color: Colors.black
),
)
],
),
)
试着继续改造,作为一个页面,不可能只有一个menu快,所以我用SingleScrollView包裹:
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'GridView实战',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: SafeArea(
child: Container(
color: Colors.cyan,
width: double.infinity,
height: double.infinity,
padding: EdgeInsets.symmetric(horizontal: 10.0),
child: SingleChildScrollView(
child: Container(
margin: EdgeInsets.only(top: 20.0),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(10))
),
padding: EdgeInsets.all(10.0),
child: GridView.count(
crossAxisSpacing: 6.0,
childAspectRatio: 1,
crossAxisCount: 5,
children: [
Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 40.0,
height: 40.0,
decoration: BoxDecoration(
color: Colors.blueAccent,
borderRadius: BorderRadius.circular(20.0)
),
child: Icon(
Icons.add,
color: Colors.white,
),
),
Text(
"文字",
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.normal,
decoration: TextDecoration.none,
color: Colors.black
),
)
],
),
),
Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 40.0,
height: 40.0,
decoration: BoxDecoration(
color: Colors.blueAccent,
borderRadius: BorderRadius.circular(20.0)
),
child: Icon(
Icons.add,
color: Colors.white,
),
),
Text(
"文字",
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.normal,
decoration: TextDecoration.none,
color: Colors.black
),
)
],
),
),
Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 40.0,
height: 40.0,
decoration: BoxDecoration(
color: Colors.blueAccent,
borderRadius: BorderRadius.circular(20.0)
),
child: Icon(
Icons.add,
color: Colors.white,
),
),
Text(
"文字",
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.normal,
decoration: TextDecoration.none,
color: Colors.black
),
)
],
),
),
Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 40.0,
height: 40.0,
decoration: BoxDecoration(
color: Colors.blueAccent,
borderRadius: BorderRadius.circular(20.0)
),
child: Icon(
Icons.add,
color: Colors.white,
),
),
Text(
"文字",
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.normal,
decoration: TextDecoration.none,
color: Colors.black
),
)
],
),
),
Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 40.0,
height: 40.0,
decoration: BoxDecoration(
color: Colors.blueAccent,
borderRadius: BorderRadius.circular(20.0)
),
child: Icon(
Icons.add,
color: Colors.white,
),
),
Text(
"文字",
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.normal,
decoration: TextDecoration.none,
color: Colors.black
),
)
],
),
),
Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 40.0,
height: 40.0,
decoration: BoxDecoration(
color: Colors.blueAccent,
borderRadius: BorderRadius.circular(20.0)
),
child: Icon(
Icons.add,
color: Colors.white,
),
),
Text(
"文字",
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.normal,
decoration: TextDecoration.none,
color: Colors.black
),
)
],
),
),
Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 40.0,
height: 40.0,
decoration: BoxDecoration(
color: Colors.blueAccent,
borderRadius: BorderRadius.circular(20.0)
),
child: Icon(
Icons.add,
color: Colors.white,
),
),
Text(
"文字",
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.normal,
decoration: TextDecoration.none,
color: Colors.black
),
)
],
),
),
Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 40.0,
height: 40.0,
decoration: BoxDecoration(
color: Colors.blueAccent,
borderRadius: BorderRadius.circular(20.0)
),
child: Icon(
Icons.add,
color: Colors.white,
),
),
Text(
"文字",
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.normal,
decoration: TextDecoration.none,
color: Colors.black
),
)
],
),
),
Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 40.0,
height: 40.0,
decoration: BoxDecoration(
color: Colors.blueAccent,
borderRadius: BorderRadius.circular(20.0)
),
child: Icon(
Icons.add,
color: Colors.white,
),
),
Text(
"文字",
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.normal,
decoration: TextDecoration.none,
color: Colors.black
),
)
],
),
),
Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 40.0,
height: 40.0,
decoration: BoxDecoration(
color: Colors.blueAccent,
borderRadius: BorderRadius.circular(20.0)
),
child: Icon(
Icons.add,
color: Colors.white,
),
),
Text(
"文字",
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.normal,
decoration: TextDecoration.none,
color: Colors.black
),
)
],
),
)
],
),
),
),
),
),
);
}
}
运行报错:
gg(某引擎)解决:
运行结果如下:
此处看到一个GridView可以在给定区域里滑动。
改动高度为适当的值:
到这里,菜单区域已经画完了。
下面继续绘制,推荐商品列表
有了前面的GridView的编写,下面我很快编写出了商品列表:
import 'package:flutter/material.dart';
void main(){
runApp(
MyApp()
);
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'GridView实战',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: SafeArea(
child: Container(
color: Colors.cyan,
width: double.infinity,
height: double.infinity,
padding: EdgeInsets.symmetric(horizontal: 10.0),
child: SingleChildScrollView(
child:Column(
children: [
Container(
height: 145.0,
margin: EdgeInsets.only(top: 20.0),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(10))
),
padding: EdgeInsets.all(10.0),
child: GridView.count(
crossAxisSpacing: 6.0,
childAspectRatio: 1,
crossAxisCount: 5,
children: [
Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 40.0,
height: 40.0,
decoration: BoxDecoration(
color: Colors.blueAccent,
borderRadius: BorderRadius.circular(20.0)
),
child: Icon(
Icons.add,
color: Colors.white,
),
),
Text(
"文字",
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.normal,
decoration: TextDecoration.none,
color: Colors.black
),
)
],
),
),
Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 40.0,
height: 40.0,
decoration: BoxDecoration(
color: Colors.blueAccent,
borderRadius: BorderRadius.circular(20.0)
),
child: Icon(
Icons.add,
color: Colors.white,
),
),
Text(
"文字",
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.normal,
decoration: TextDecoration.none,
color: Colors.black
),
)
],
),
),
Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 40.0,
height: 40.0,
decoration: BoxDecoration(
color: Colors.blueAccent,
borderRadius: BorderRadius.circular(20.0)
),
child: Icon(
Icons.add,
color: Colors.white,
),
),
Text(
"文字",
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.normal,
decoration: TextDecoration.none,
color: Colors.black
),
)
],
),
),
Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 40.0,
height: 40.0,
decoration: BoxDecoration(
color: Colors.blueAccent,
borderRadius: BorderRadius.circular(20.0)
),
child: Icon(
Icons.add,
color: Colors.white,
),
),
Text(
"文字",
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.normal,
decoration: TextDecoration.none,
color: Colors.black
),
)
],
),
),
Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 40.0,
height: 40.0,
decoration: BoxDecoration(
color: Colors.blueAccent,
borderRadius: BorderRadius.circular(20.0)
),
child: Icon(
Icons.add,
color: Colors.white,
),
),
Text(
"文字",
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.normal,
decoration: TextDecoration.none,
color: Colors.black
),
)
],
),
),
Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 40.0,
height: 40.0,
decoration: BoxDecoration(
color: Colors.blueAccent,
borderRadius: BorderRadius.circular(20.0)
),
child: Icon(
Icons.add,
color: Colors.white,
),
),
Text(
"文字",
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.normal,
decoration: TextDecoration.none,
color: Colors.black
),
)
],
),
),
Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 40.0,
height: 40.0,
decoration: BoxDecoration(
color: Colors.blueAccent,
borderRadius: BorderRadius.circular(20.0)
),
child: Icon(
Icons.add,
color: Colors.white,
),
),
Text(
"文字",
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.normal,
decoration: TextDecoration.none,
color: Colors.black
),
)
],
),
),
Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 40.0,
height: 40.0,
decoration: BoxDecoration(
color: Colors.blueAccent,
borderRadius: BorderRadius.circular(20.0)
),
child: Icon(
Icons.add,
color: Colors.white,
),
),
Text(
"文字",
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.normal,
decoration: TextDecoration.none,
color: Colors.black
),
)
],
),
),
Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 40.0,
height: 40.0,
decoration: BoxDecoration(
color: Colors.blueAccent,
borderRadius: BorderRadius.circular(20.0)
),
child: Icon(
Icons.add,
color: Colors.white,
),
),
Text(
"文字",
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.normal,
decoration: TextDecoration.none,
color: Colors.black
),
)
],
),
),
Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 40.0,
height: 40.0,
decoration: BoxDecoration(
color: Colors.blueAccent,
borderRadius: BorderRadius.circular(20.0)
),
child: Icon(
Icons.add,
color: Colors.white,
),
),
Text(
"文字",
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.normal,
decoration: TextDecoration.none,
color: Colors.black
),
)
],
),
)
],
),
),
Container(
decoration: BoxDecoration(
color: Colors.white
),
child: GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2, //每行三列
childAspectRatio: 0.5 //显示区域宽高相等
),
itemCount: 10,
itemBuilder: (context, index) {
return Column(
children: [
Image.network("http://yujun-x-store.img.abc188.com/tianyao_cloud/1.png"),
Text("产品标题"),
],
);
}
),
)
],
),
),
),
),
);
}
}
运行报错:
解决方式前面也提过:
改造之后重新运行:
问题是解决了,但是这也不是我们要的结果呀,商品推荐怎么可以确定有多少,那么这个外层高度就是不确定的。而且商品推荐列表不应该单独滑动。
继续改造:
运行结果如下:
完整代码如下:
import 'package:flutter/material.dart';
void main(){
runApp(
MyApp()
);
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'GridView实战',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: SafeArea(
child: Container(
color: Colors.cyan,
width: double.infinity,
height: double.infinity,
padding: EdgeInsets.symmetric(horizontal: 10.0),
child: SingleChildScrollView(
child:Column(
children: [
Container(
height: 145.0,
margin: EdgeInsets.only(top: 20.0),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(10))
),
padding: EdgeInsets.all(10.0),
child: GridView.count(
crossAxisSpacing: 6.0,
childAspectRatio: 1,
crossAxisCount: 5,
physics: NeverScrollableScrollPhysics(),
children: [
Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 40.0,
height: 40.0,
decoration: BoxDecoration(
color: Colors.blueAccent,
borderRadius: BorderRadius.circular(20.0)
),
child: Icon(
Icons.add,
color: Colors.white,
),
),
Text(
"文字",
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.normal,
decoration: TextDecoration.none,
color: Colors.black
),
overflow: TextOverflow.ellipsis,
)
],
),
),
Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 40.0,
height: 40.0,
decoration: BoxDecoration(
color: Colors.blueAccent,
borderRadius: BorderRadius.circular(20.0)
),
child: Icon(
Icons.add,
color: Colors.white,
),
),
Text(
"文字",
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.normal,
decoration: TextDecoration.none,
color: Colors.black
),
)
],
),
),
Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 40.0,
height: 40.0,
decoration: BoxDecoration(
color: Colors.blueAccent,
borderRadius: BorderRadius.circular(20.0)
),
child: Icon(
Icons.add,
color: Colors.white,
),
),
Text(
"文字",
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.normal,
decoration: TextDecoration.none,
color: Colors.black
),
)
],
),
),
Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 40.0,
height: 40.0,
decoration: BoxDecoration(
color: Colors.blueAccent,
borderRadius: BorderRadius.circular(20.0)
),
child: Icon(
Icons.add,
color: Colors.white,
),
),
Text(
"文字",
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.normal,
decoration: TextDecoration.none,
color: Colors.black
),
)
],
),
),
Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 40.0,
height: 40.0,
decoration: BoxDecoration(
color: Colors.blueAccent,
borderRadius: BorderRadius.circular(20.0)
),
child: Icon(
Icons.add,
color: Colors.white,
),
),
Text(
"文字",
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.normal,
decoration: TextDecoration.none,
color: Colors.black
),
)
],
),
),
Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 40.0,
height: 40.0,
decoration: BoxDecoration(
color: Colors.blueAccent,
borderRadius: BorderRadius.circular(20.0)
),
child: Icon(
Icons.add,
color: Colors.white,
),
),
Text(
"文字",
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.normal,
decoration: TextDecoration.none,
color: Colors.black
),
)
],
),
),
Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 40.0,
height: 40.0,
decoration: BoxDecoration(
color: Colors.blueAccent,
borderRadius: BorderRadius.circular(20.0)
),
child: Icon(
Icons.add,
color: Colors.white,
),
),
Text(
"文字",
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.normal,
decoration: TextDecoration.none,
color: Colors.black
),
)
],
),
),
Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 40.0,
height: 40.0,
decoration: BoxDecoration(
color: Colors.blueAccent,
borderRadius: BorderRadius.circular(20.0)
),
child: Icon(
Icons.add,
color: Colors.white,
),
),
Text(
"文字",
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.normal,
decoration: TextDecoration.none,
color: Colors.black
),
)
],
),
),
Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 40.0,
height: 40.0,
decoration: BoxDecoration(
color: Colors.blueAccent,
borderRadius: BorderRadius.circular(20.0)
),
child: Icon(
Icons.add,
color: Colors.white,
),
),
Text(
"文字",
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.normal,
decoration: TextDecoration.none,
color: Colors.black
),
)
],
),
),
Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
width: 40.0,
height: 40.0,
decoration: BoxDecoration(
color: Colors.blueAccent,
borderRadius: BorderRadius.circular(20.0)
),
child: Icon(
Icons.add,
color: Colors.white,
),
),
Text(
"文字",
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.normal,
decoration: TextDecoration.none,
color: Colors.black
),
)
],
),
)
],
),
),
Container(
// height: 500,
margin: EdgeInsets.only(top: 20),
decoration: BoxDecoration(
color: Colors.white
),
child: GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3, //每行三列
childAspectRatio: 0.8 //显示区域宽高相等
),
itemCount: 24,
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemBuilder: (context, index) {
return Column(
children: [
Image.network("http://yujun-x-store.img.abc188.com/tianyao_cloud/1.png"),
Text(
"产品标题",
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.normal,
decoration: TextDecoration.none,
color: Colors.black
),
overflow: TextOverflow.ellipsis,
),
],
);
}
),
)
],
),
),
),
),
);
}
}
写代码一定要有“纸上得来终觉浅”的觉悟,书上别人的代码只能告诉你大概的用法,具体项目中需要解决的问题还是路漫漫其修远兮~