Flutter学习

Flutter学习--布局之Row/Column/Stack

2020-04-22  本文已影响0人  文小猿666

Flutter中布局以 Row Column Stack 为主

一.Alignment

一般来说,Align的使用都是其他控件的一个参数,目的是为了设置子child的对齐方式,比如居中,左上,右下等多个对齐方向,其本身用法也多灵活。
如Alignment(0.0,0.0) == Alignment.center ,都是将子child居中对齐的控制方式
一个栗子🌰
根据设置aliginment参数的值可以调整子child的位置

class LayoutDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.yellow,
      alignment: Alignment(-1, 0),//
      child: Text(
        '泥猴桃',
        style: TextStyle(fontSize: 28,color: Colors.red),
      ),
    );
  }
}
图片.png

二.Row Cloumn Stack

1.Row(横向)

在Flutter中非常常见的一个多子节点控件,将children排列成一行。
例子:

class LayoutDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.yellow,
      alignment: Alignment(0, 0),//
      child: Row(
        children: <Widget>[
          Container(width: 50,height: 50,color: Colors.red,),
          Container(width: 50,height: 50,color: Colors.blue,),
          Container(width: 50,height: 50,color: Colors.white,),
        ],
      )
    );
  }
}

实现效果为


图片.png

mainAxisAlignment(主轴)

在水平方向控件如Row中MainAxisAlignment(主轴)就是与当前控件方向一致的轴,而CrossAxisAlignment(交叉轴)就是与当前控件方向垂直的轴

它是一个枚举值

enum MainAxisAlignment {
 //将子控件放在主轴的开始位置
  start,  
   //将子控件放在主轴的结束位置
  end,
  //将子控件放在主轴的中间位置
  center,
  //将主轴空白位置进行均分,排列子元素,手尾没有空隙
  spaceBetween,
  //将主轴空白区域均分,使中间各个子控件间距相等,首尾子控件间距为中间子控件间距的一半
  spaceAround,
  //将主轴空白区域均分,使各个子控件间距相等
  spaceEvenly,
}

我们可以写三个组件一一调试一下 spaceBetween

class LayoutDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
        color: Colors.yellow,
        alignment: Alignment(0, 0), 
        child: Row(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
//        crossAxisAlignment: Cro,
          children: <Widget>[
            Container(
                width: 100,
                height: 100,
                color: Colors.red,
                child: Text(
                  '1',
                  textAlign: TextAlign.center,
                  style: TextStyle(fontSize: 60),
                )),
            Container(
                width: 100,
                height: 100,
                color: Colors.blue,
                child: Text(
                  '2',
                  textAlign: TextAlign.center,
                  style: TextStyle(fontSize: 60),
                )),
            Container(
                width: 100,
                height: 100,
                color: Colors.white,
                child: Text(
                  '3',
                  textAlign: TextAlign.center,
                  style: TextStyle(fontSize: 60),
                )),
          ],
        ));
  }
}

效果如下


图片.png

添加

textDirection: TextDirection.rtl

可以改变MainAxisAlignment的起始位置和排列方向


图片.png

crossAxisAlignment(交叉轴)

CrossAxisAlignment是垂直的,默认起始位置在中间,排列方向为从上至下,此时可以通过verticalDirection来改变CrossAxisAlignment的起始位置及排列方向

枚举值有:

enum CrossAxisAlignment {
 //将子控件放在交叉轴的起始位置
  start,
 //将子控件放在交叉轴的结束位置
  end,
 //将子控件放在交叉轴的中间位置
  center,
//使子控件填满交叉轴
  stretch,
//将子控件放在交叉轴的上,并且与基线相匹配(不常用)
  baseline,
}

这里注意baselin需要与子控件的约束一起使用,不能单独使用,否则会报错。

添加

verticalDirection: VerticalDirection.up,

效果如下


图片.png

可以改变CrossAxisAlignment的起始位置及排列方向

2.Cloumn
跟Row很相似,这里就不赘述了

3.Stack
这个组件跟iOS中的布局方式很像,子视图按层级叠加。

Stack({
  Key key,
  this.alignment = AlignmentDirectional.topStart,
  this.textDirection,
  this.fit = StackFit.loose,
  this.overflow = Overflow.clip,
  List<Widget> children = const <Widget>[],
})

alignment : 指的是子Widget的对其方式,默认情况是以左上角为开始点 ,这个属性是最难理解的,它区分为使用了Positioned和未使用Positioned定义两种情况,没有使用Positioned情况还是比较好理解的,下面会详细讲解的
fit :用来决定没有Positioned方式时候子Widget的大小,StackFit.loose 指的是子Widget 多大就多大,StackFit.expand使子Widget的大小和父组件一样大
overflow :指子Widget 超出Stack时候如何显示,默认值是Overflow.clip,子Widget超出Stack会被截断

Positioned
这个使用控制Widget的位置,通过他可以随意摆放一个组件,有点像绝对布局

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

left、top 、right、 bottom分别代表离Stack左、上、右、底四边的距离

class StackDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      alignment: Alignment(0, 0),
      color: Colors.yellowAccent,
      child: Stack(
        alignment: Alignment(0, 0),
        children: <Widget>[
          Positioned(
            right: 0,//距离左边距为0
            child: Container(
              color: Colors.white,
              width: 200,
              height: 200,
             ),
          ),
          Positioned(
            left: 0,//距离右边距为0
            child: Container(
                color: Colors.green,
                width: 100,
                height: 100,
              ),
          ),
          Positioned(
            right: 250,//距离右边距为0
            child: Container(
              color: Colors.blue,
              width: 50,
              height: 50,
            ),
          ),
        ],
      ),
    );
  }
}

效果如下


图片.png

AspectRatio
设置控件的宽高比
如下,设置控件的宽度,经过计算可得到控件的高度为100

class LayoutDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.red,
//      alignment: Alignment(0, 0),
      width: 200,
      child: AspectRatio(
        aspectRatio: 2/1,
//        child: Container(
//        ),
      )
    );
  }
}

效果如下


图片.png

三.Expanded(填充式布局/灵活布局)

源码如下

class Expanded extends Flexible {
  const Expanded({
    Key key,
    int flex = 1,
    @required Widget child,
  }) : super(key: key, flex: flex, fit: FlexFit.tight, child: child);
}

举个例子

class LayoutDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
        color: Colors.yellow,
        alignment: Alignment(0, 0), //
        child: Row(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          crossAxisAlignment: CrossAxisAlignment.baseline,
          textBaseline: TextBaseline.ideographic,
          textDirection: TextDirection.ltr,
          verticalDirection: VerticalDirection.up,
          children: <Widget>[
            Expanded(child: Container(
                width: 80,
                height: 80,
                color: Colors.red,
                child: Text(
                  'hahah',
                  textAlign: TextAlign.center,
                  style: TextStyle(fontSize: 60),
                )),
            ),
            Expanded(child: Container(
                width: 120,
                height: 120,
                color: Colors.blue,
                child: Text(
                  'xixixi',
                  textAlign: TextAlign.center,
                  style: TextStyle(fontSize: 60),
                )),
            ),
            Expanded(child: Container(
                width: 160,
                height: 160,
                color: Colors.white,
                child: Text(
                  'yoyoyo',
                  textAlign: TextAlign.center,
                  style: TextStyle(fontSize: 60),
                )),
            ),

          ],
        ));
  }
}

实现效果为


图片.png
上一篇下一篇

猜你喜欢

热点阅读