本文目录
-
- 前言
- GridView
- CustomScrollView
- Flex
- Wrap
上一篇介绍了多元素组件:ListView,Scaffold,AppBar,Row,Column,这一节将接着上一篇博文,介绍GridView,CustomScrollView,Flex,以及Wrap多元素组件(下图为CustomScrollView实现效果)
首先,就是GridView,它和ListView相似,只不过表现形式为网格形式,可以把它看成Android的LayoutManager。如果GridView组件掌握的很好,那么App界面也是会非常好看,给人赏心悦目。不过需要注意的是,GridView中的gridDelegate属性,其类型是SliverGridDelegate,是一个抽象类,通过该类可以控制GridView的排列显示方式,我们先来看看官方文档的使用方式:
body: GridView.count(
primary: false,
padding: const EdgeInsets.all(20.0),
crossAxisSpacing: 10.0,
crossAxisCount: 2,
children: <Widget>[
const Text("11111111111111111111"),
const Text("22222222222222222222"),
const Text("33333333333333333333"),
const Text("44444444444444444444"),
const Text("55555555555555555555"),
const Text("66666666666666666666"),
],
),
这里我们没有看到代码中使用SliverGridDelegate,那么它在哪里呢?其实,在GridView.count中的构造函数里已经传入了默认的gridDelegate,通过开发工具我们进入它的源码:
gridDelegate = SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: crossAxisCount,
mainAxisSpacing: mainAxisSpacing,
crossAxisSpacing: crossAxisSpacing,
childAspectRatio: childAspectRatio,
),
源码里已经使用了SliverGridDelegateWithFixedCrossAxisCount。它有四个属性,我们先来看看他们的定义:
属性 | 取值 |
---|---|
crossAxisCount | 横向轴子元素的数量 |
mainAxisSpacing | 横向轴之间的间距 |
crossAxisSpacing | 子元素之间的间距 |
childAspectRatio | 子元素的宽高比,比如2.0就表示宽度是高度的2倍 |
gridDelegate还支持SliverGridDelegateWithMaxCrossAxisExtent,同时GridView也和ListView一样支持GridView.builder来创建,使用代码与ListView差不多,这里就不在赘述了,上面代码实现效果如下:
在实际应用里,布局情况并不是非此即彼,一般一个界面不会只有一个滚动列表组件,很可能还有别的组件,这个时候CustomScrollView就有用处了,它的使用代码如下:
return CustomScrollView(
slivers: <Widget>[
const SliverAppBar(
pinned: true,//标题栏是否固定
expandedHeight: 250.0,//合并的高度,默认是状态栏的高度加AppBar的高度
flexibleSpace: FlexibleSpaceBar(
title: Text("我的标题"),
),
),
SliverGrid(
delegate: SliverChildBuilderDelegate((BuildContext context,int index){
return Container(
alignment: Alignment.center,
color: Colors.teal[100*(index%9)],
child: Text("第$index个"),
);
},childCount: 20),
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
maxCrossAxisExtent: 200.0,//单个子Widget的水平最大宽度
mainAxisSpacing: 10.0,//水平单个子Widget之间间距
crossAxisSpacing: 10.0,//垂直单个子Widget之间间距
childAspectRatio: 4.0,//宽高比
)
),
SliverFixedExtentList(
itemExtent: 50.0,
delegate: SliverChildBuilderDelegate((BuildContext context,int index){
return Container(
alignment: Alignment.center,
color: Colors.lightBlue[100*(index%9)],
child: Text("第$index个"),
);
}),
),
],
);
这段代码看起来非常复杂其实很好理解,在Scaffold中,Appbar等价于SliverAppBar,刚讲解的GridView等价于SliverGrid,而ListView等价于SliverFixedExtentList,所以这是一个包含了二个滑动组件的一个布局容器,其他的代码中有注释,这里就不赘述了。(显示效果如博文首图)
特别注意:转换后的组件都是以“Sliver”开头的,其本身是不具备滚动特性的,但是放在CustomScrollView中之后,则可以实现滚动的功能。
Flex英文意思是屈伸,活动,在Flutter里面也就是弹性布局,该布局借鉴了前端里的Flex布局方式。用法也十分简单,我们可以在Flex中传入一些参数,其具体属性如下表:
direction | Axis.vertical表示垂直方向,Axis.horizontal表示水平方向 |
flex | 弹性系数,大于0会按比例来分割,等于0不会扩展占用的空间 |
可以把它理解为android:layout_weight属性,使用代码如下:
return Scaffold(
appBar: AppBar(title: Text("Flex布局玩法"),),
body: Column(
children: <Widget>[
Container(
height: 400.0,
child: Flex(
direction: Axis.vertical,
children: <Widget>[
Expanded(
flex: 1,
child: Container(
color: Colors.red,
),
),
Expanded(
flex: 2,
child: Container(
color: Colors.yellow,
),
),
],
),
),
Container(
height: 120.0,
child: new Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Expanded(
flex: 2,
child: Container(
color: Colors.blueAccent,
),
),
Expanded(
flex: 1,
child: Container(
color: Colors.red,
),
),
],
),
),
],
),
);
return Scaffold(
appBar: AppBar(title: Text("Wrap组件玩法"),),
body: Wrap(
spacing: 4.0,
runSpacing: 4.0,
children: <Widget>[
Container(
color: Colors.yellow,
child: Text("Python编程指南",style: new TextStyle(color: Colors.lightBlue),),
),
Container(
color: Colors.yellow,
child: Text("Android编程指南",style: new TextStyle(color: Colors.lightBlue),)
),
Container(
color: Colors.yellow,
child: Text("Flutter",style: new TextStyle(color: Colors.lightBlue),)
),
Container(
color: Colors.yellow,
child: Text("VUE",style: new TextStyle(color: Colors.lightBlue),)
),
Container(
color: Colors.yellow,
child: Text("Scaffold",style: new TextStyle(color: Colors.lightBlue),)
),
Container(
color: Colors.yellow,
child: Text("Container",style: new TextStyle(color: Colors.lightBlue),)
),
Container(
color: Colors.yellow,
child: Text("Colors",style: new TextStyle(color: Colors.lightBlue),)
),
Container(
color: Colors.yellow,
child: Text("Colors.yellow",style: new TextStyle(color: Colors.lightBlue),)
),
],
),
);