赞
踩
上一篇介绍了多元素组件: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, ), ), ], ), ), ], ), );
上面的例子中,我们实现了Flex布局。这种布局还有一种方式,它通过在Row组件里设置两边对齐也可以实现,代码显示效果如下:
Wrap英文字面是包裹的意思,在前端开发中,我们通常把具有相同的布局整合在一个大的布局组件之内,比如说前面一节使用Row去包裹一些组件,因为它是多子元素组件,但是Row有时候会出问题,比如实际子组件超过屏幕,在这种情况下,我们就需要使用Wrap去代替Row组件,使用代码如下:
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),) ), ], ), );
其实就是自适应控件布局容器,当一行放不下的时候会自动换行显示,这在Java开发中并没有配套的控件,需要自定义View,而Flutter开发中,直接提供了该组件,实现效果如下:
多子元素组件到这里就全部讲解完成,下一篇博文将介绍Flutter状态管理。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。