美文网首页
《Flutter实战》第四章

《Flutter实战》第四章

作者: 番茄tomato | 来源:发表于2020-05-08 18:01 被阅读0次
  • 本篇参考资料《Flutter实战》
  • 本篇文章只是本人看书的理解和整理的笔记,更完整的内容还在书上!
  • 电子书链接:https://book.flutterchina.club/
  • Flutter中文社区链接:https://flutterchina.club/
  • 尊重原作者,能支持购买实体书当然最好

一.线性布局Row和Column

提到线性布局,我们第一个需要掌握的概念就是主轴和纵轴
Row横向布局的主轴就是水平方向,纵轴就是垂直方向
Column垂直布局主轴就是垂直方向,纵轴就水平方向

image.png
mainAxisSize是控制布局大小的属性,有MainAxisSize.min和max,min表示大小和内部控件大小之和相等,max表示填充完父控件。如果Row里面嵌套Row,或者Column里面再嵌套Column,那么只有最外面的Row或Column会占用尽可能大的空间,里面Row或Column所占用的空间为实际大小,使用Expanded可以灵活改变内部控件大小。

二.弹性布局

弹性布局通常是Expanded属性flex的使用,类似于Android中的View比重weight这个属性,可以使用与Flex,Row和Column三个布局中。
Flex是Row和Column的父类,它有一个属性direction可以设置子控件排列方向
弹性布局用法如下:

//Flex的两个子widget按1:2来占据水平空间  
        Flex(
          direction: Axis.horizontal,
          children: <Widget>[
            Expanded(
              flex: 1,
              child: Container(
                height: 30.0,
                color: Colors.red,
              ),
            ),
            Expanded(
              flex: 2,
              child: Container(
                height: 30.0,
                color: Colors.green,
              ),
            ),
          ],
        )

三.流式布局

流式布局有两个Wrap和Flow,我们通常使用Wrap。
Wrap能在子控件在主轴超出范围时,自动折行,除此之外其他的属性和Flex都一样。
Wrap主轴水平的时候,高度允许的情况下进行折行
Wrap主轴竖直的时候,宽度允许的情况下进行折列


image.png
          Wrap(
              direction: Axis.horizontal,
              spacing: 5.0,
              //主轴间距
              runSpacing: 1,
              //纵轴间距
              alignment: WrapAlignment.center,
              //沿主轴方向居中
              children: <Widget>[
                new Chip(
                  avatar: new CircleAvatar(
                      backgroundColor: Colors.blue, child: Text('A')),
                  label: new Text('Hamilton'),
                ),
                new Chip(
                  avatar: new CircleAvatar(
                      backgroundColor: Colors.blue, child: Text('M')),
                  label: new Text('Lafayette'),
                ),
                new Chip(
                  avatar: new CircleAvatar(
                      backgroundColor: Colors.blue, child: Text('H')),
                  label: new Text('Mulligan'),
                ),
                new Chip(
                  avatar: new CircleAvatar(
                      backgroundColor: Colors.blue, child: Text('J')),
                  label: new Text('Laurens'),
                ),
              ]),
          Container(
            height: 200,
            width: 200,
            color: Colors.grey[200],
            child: Wrap(
              direction: Axis.vertical,
              spacing: 5,
              //主轴间距
              runSpacing: 5,
              children: <Widget>[
                Container(height: 50, width: 20, color: Colors.pink[100],),
                Container(height: 50, width: 20, color: Colors.pink[100],),                
                Container(height: 50, width: 20, color: Colors.pink[100],),
                Container(height: 50, width: 20, color: Colors.pink[100],),                
                Container(height: 50, width: 20, color: Colors.pink[100],),
                Container(height: 50, width: 20, color: Colors.pink[100],),
                Container(height: 50, width: 20, color: Colors.pink[100],),
                Container(height: 50, width: 20, color: Colors.pink[100],),                
                Container(height: 50, width: 20, color: Colors.pink[100],),
                Container(height: 50, width: 20, color: Colors.pink[100],),
                Container(height: 50, width: 20, color: Colors.pink[100],),
                Container(height: 50, width: 20, color: Colors.pink[100],),
                Container(height: 50, width: 20, color: Colors.pink[100],)
              ],
            ),
          ),

三.叠层布局

叠层布局有点像Android的RelativeLayout相对布局,可以设置子元素相对于Stack四边的距离来控制位置和大小,Stack通常是配合Positioned一起使用,比如左上角距离左边20,顶部20的粉色方块:

Stack(
            alignment: Alignment.center, //指定未定位或部分定位widget的对齐方式
            fit: StackFit.loose, //指定未确定大小的子组件默认大小
            children: <Widget>[
              Positioned(
                  left: 10,
                  top: 10,
                  child: Container(
                    height: 20,
                    width: 20,
                    color: Colors.pink[200],
                  )
              ),
)

Positioned有如下8个属性:

const Positioned({
  Key key,
  this.left, 
  this.top,
  this.right,
  this.bottom,
  this.width,
  this.height,
  @required Widget child,
})

left、top 、right、 bottom分别代表离Stack左、上、右、底四边的距离。width和height用于指定需要定位元素的宽度和高度。注意,Positioned的width、height 和其它地方的意义稍微有点区别,此处用于配合left、top 、right、 bottom来定位组件,举个例子,在水平方向时,你只能指定left、right、width三个属性中的两个,如指定left和width后,right会自动算出(left+width),如果同时指定三个属性则会报错,垂直方向同理。
也就是说我同时指定距离左边和右边的距离后,子空间的宽度会被自动算出来,这时候在子控件内的宽度失效。

在实际开发布局中,尽量使用相对的方式来确定组件的位置和大小,以适应不同的手机屏幕

相关文章

网友评论

      本文标题:《Flutter实战》第四章

      本文链接:https://www.haomeiwen.com/subject/uslnwhtx.html