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

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
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,544评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,430评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,764评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,193评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,216评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,182评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,063评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,917评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,329评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,543评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,722评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,425评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,019评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,671评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,825评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,729评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,614评论 2 353

推荐阅读更多精彩内容