Flutter-基础组件三

1.容器组件

1)Container

常用属性:

  • key:Container唯一标识符,用于查找更新。
  • alignment:控制child的对齐方式,如果container或者container父节点尺寸大于child的尺寸,这个属性设置会起作用,有很多种对齐方式。
  • padding:decoration内部的空白区域,如果有child的话,child位于padding内部。padding与margin的不同之处在于,padding是包含在content内,而margin则是外部边界,设置点击事件的话,padding区域会响应,而margin区域不会响应。
  • color:用来设置container背景色,如果foregroundDecoration设置的话,可能会遮盖color效果。
  • decoration:绘制在child后面的装饰,设置了decoration的话,就不能设置color属性,否则会报错。可以设置背景图片、边框、阴影等跟iOS中CALayer差不多。
  • foregroundDecoration:绘制在child前面的装饰。
  • width:container的宽度,设置为double.infinity可以强制在宽度上撑满,不设置,则根据child和父节点两者一起布局。
  • height:container的高度,设置为double.infinity可以强制在高度上撑满。
  • constraints:添加到child上额外的约束条件。
  • margin:围绕在decoration和child之外的空白区域,不属于内容区域。
  • transform:设置container的变换矩阵,类型为Matrix4。
  • child:container中的内容widget。

2)Padding
作为一个基础的控件,功能非常单一,给子节点设置padding属性。

Padding的布局分为两种情况:

  • 当child为空的时候,会产生一个宽为left+right,高为top+bottom的区域;
  • 当child不为空的时候,Padding会将布局约束传递给child,根据设置的padding属性,缩小child的布局尺寸。然后Padding将自己调整到child设置了padding属性的尺寸,在child周围创建空白区域。

源码:

const Padding({
    Key key,
    @required this.padding, //设置内边距
    Widget child, // 子控件
  })

2)Align

Align的布局行为分为两种情况:

  • 当widthFactor和heightFactor为null的时候,当其有限制条件的时候,Align会根据限制条件尽量的扩展自己的尺寸,当没有限制条件的时候,会调整到child的尺寸;
  • 当widthFactor或者heightFactor不为null的时候,Aligin会根据factor属性,扩展自己的尺寸,例如设置widthFactor为2.0的时候,那么,Align的宽度将会是child的两倍。

源码:

const Align({
    Key key,
    this.alignment: Alignment.center,
    this.widthFactor,// 宽度因子,如果设置的话,Align的宽度就是child的宽度乘以这个值,不能为负数。不设置的话则尽量扩展。
    this.heightFactor,// 高度因子,如果设置的话,Align的高度就是child的高度乘以这个值,不能为负数。不设置的话则尽量扩展。
    Widget child
  })

3)Center
Center继承自Align,,只不过是将alignment设置为Alignment.center,其他属性例如widthFactor、heightFactor,布局行为,都与Align完全一样。

源码:

class Center extends Align {
  /// Creates a widget that centers its child.
  const Center({ Key key, double widthFactor, double heightFactor, Widget child })
    : super(key: key, widthFactor: widthFactor, heightFactor: heightFactor, child: child);
}

4)FittedBox

布局行为分两种情况:

  • 如果外部有约束的话,按照外部约束调整自身尺寸,然后缩放调整child,按照指定的条件进行布局;
  • 如果没有外部约束条件,则跟child尺寸一致,指定的缩放以及位置属性将不起作用。

FittedBox会在自己的尺寸范围内缩放并且调整child位置,使得child适合其尺寸。

源码:

 const FittedBox({
    Key key,
    this.fit = BoxFit.contain,
    this.alignment = Alignment.center,
    this.clipBehavior = Clip.hardEdge,
    Widget child,
  })

示例:

Container(
  color: Colors.amberAccent,
  width: 300.0,
  height: 300.0,
  child: new FittedBox(
    fit: BoxFit.contain,
    alignment: Alignment.topLeft,
    child: new Container(
      color: Colors.red,
      child: new Text("FittedBox"),
    ),
  ),
)

5)SizedBox

SizedBox布局行为:

  • child不为null时,如果设置了宽高,则会强制把child尺寸调到此宽高;如果没有设置宽高,则会根据child尺寸进行调整;
  • child为null时,如果设置了宽高,则自身尺寸调整到此宽高值,如果没设置,则尺寸为0;

源码:

const SizedBox({ 
Key key, 
this.width, 
this.height, 
Widget child })

示例:

ontainer(
  color: Colors.green,
  padding: const EdgeInsets.all(5.0),
  child: SizedBox(
    width: 200.0,
    height: 200.0,
    child: Container(
      color: Colors.red,
      width: 100.0,
      height: 300.0,
    ),
  ),
)
2.布局组件

1)Flex
弹性布局允许子组件按照一定比例来分配父容器空间。Flex组件可以沿着水平或垂直方向排列子组件,如果你知道主轴方向,使用Row或Column会方便一些,因为Row和Column都继承自Flex,参数基本相同,所以能使用Flex的地方基本上都可以使用Row或Column。Flex本身功能是很强大的,它也可以和Expanded组件配合实现弹性布局。

Flex({
    Key key,
    @required this.direction,
    this.mainAxisAlignment = MainAxisAlignment.start,
    this.mainAxisSize = MainAxisSize.max,
    this.crossAxisAlignment = CrossAxisAlignment.center,
    this.textDirection,
    this.verticalDirection = VerticalDirection.down,
    this.textBaseline,
    this.clipBehavior = Clip.hardEdge,
    List<Widget> children = const <Widget>[],
  })

  • direction:主轴方向。
  • MainAxisAlignment:主轴方向上的对齐方式,会对child的位置起作用,默认是start。
MainAxisAlignment枚举值:  
center:将children放置在主轴的中心;  
end:将children放置在主轴的末尾;  
spaceAround:将主轴方向上的空白区域均分,使得children之间的空白区域相等,但是首尾child的空白区域为1/2; 
spaceBetween:将主轴方向上的空白区域均分,使得children之间的空白区域相等,首尾child都靠近首尾,没有间隙;
spaceEvenly:将主轴方向上的空白区域均分,使得children之间的空白区域相等,包括首尾child;
start:将children放置在主轴的起点;
  • MainAxisSize:在主轴方向占有空间的值,默认是max。根据传入的布局约束条件,最大化主轴方向的可用空间;min,与max相反,是最小化主轴方向的可用空间。
  • CrossAxisAlignment:children在交叉轴方向的对齐方式,与MainAxisAlignment略有不同。
CrossAxisAlignment枚举值有如下几种:

baseline:在交叉轴方向,使得children的baseline对齐;
center:children在交叉轴上居中展示;
end:children在交叉轴上末尾展示;
start:children在交叉轴上起点处展示;
stretch:让children填满交叉轴方向;

  • TextDirection:阿拉伯语系的兼容设置,一般无需处理。
  • VerticalDirection:定义了children摆放顺序,默认是down,从top到bottom进行布局。up,从bottom到top进行布局。
  • TextBaseline:字符对其方式。

Expanded组件可以使Row、Column、Fiex等子组件在其主轴上方向展开并填充可用的空间。

源码:

const Expanded({
    Key key,
    int flex = 1,flex // 分配空间的弹性系数,Row,Column或Flex的每个Expanded的flex构成空间分配的比例,默认int flex = 1
    @required Widget child,
  })

示例:

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,
      ),
    ),
  ],
),

2)Row、Column

将children排列成一行或者一列,自身不带滚动属性,如果超出了一行,在debug下面则会显示溢出的提示。

源码:

Row({
  Key key,
  MainAxisAlignment mainAxisAlignment = MainAxisAlignment.start,
  MainAxisSize mainAxisSize = MainAxisSize.max,
  CrossAxisAlignment crossAxisAlignment = CrossAxisAlignment.center,
  TextDirection textDirection,
  VerticalDirection verticalDirection = VerticalDirection.down,
  TextBaseline textBaseline,
  List<Widget> children = const <Widget>[],
})

Flex的构造函数就比Row和Column的多了一个参数。Row跟Column的区别,正是这个direction参数的不同。当为Axis.horizontal的时候,则是Row,当为Axis.vertical的时候,则是Column。

示例:

Row(
  children: <Widget>[
    Expanded(
      child: Container(
        color: Colors.red,
        padding: EdgeInsets.all(5.0),
      ),
      flex: 1,
    ),
    Expanded(
      child: Container(
        color: Colors.yellow,
        padding: EdgeInsets.all(5.0),
      ),
      flex: 2,
    ),
    Expanded(
      child: Container(
        color: Colors.blue,
        padding: EdgeInsets.all(5.0),
      ),
      flex: 1,
    ),
  ],
)

3)Stack

Stack可以类比web中的absolute,绝对布局。对于绘制child的顺序,则是第一个child被绘制在最底端,后面的依次在前一个child的上面,类似于web中的z-index。如果想调整显示的顺序,则可以通过摆放child的顺序来进行。

源码:

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的子节点,它们的位置会根据所设置的top、bottom、right以及left属性来确定,这几个值都是相对于Stack的左上角。
    对于non-positioned的子节点,它们会根据Stack的aligment来设置位置。
  • fit :用来决定没有Positioned方式时候子Widget的大小,StackFit.loose 指的是子Widget 多大就多大,StackFit.expand使子Widget的大小和父组件一样大。
  • overflow :指子Widget超出Stack时候如何显示,默认值是Overflow.clip,子Widget超出Stack会被截断,Overflow.visible超出部分还会显示的。

Positioned:
源码:

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

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

示例:

Stack(
    children: <Widget>[
      Positioned(
        top: 100.0,
        child: Container(
          color: Colors.blue,
          child: Text("第一个组件"),
        ),
      ),
      Positioned(
        top: 200,
        right: 100,
        child: Container(
          color: Colors.yellow,
          child: Text("第二个组件"),
        ),
      ),
      Positioned(
        left: 100.0,
        child: Container(
          color: Colors.red,
          child: Text("第三个组件"),
        ),
      ),
    ],
 ),

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