美文网首页Flutter学习
Flutter学习--布局之Row/Column/Stack

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

作者: 文小猿666 | 来源:发表于2020-04-22 14:55 被阅读0次

    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

    相关文章

      网友评论

        本文标题:Flutter学习--布局之Row/Column/Stack

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