Flutter组件解析之Container

Flutter使用声明式来写UI,跟SwiftUI类似,非常先进。但是与HTML或以前的iOS布局方式差异相当大,这里主要通过介绍万金油组件Container来熟悉这种写法。

一、源码解析

Container实现了很多功能,很多时候有多种需要的时候一个Container就可以搞定。 我们来看看Container的创建源码,每个参数其实都是嵌套了一层小组件,这里把相应的小组件写在后面注释里面了。

Container({
  Key key,
  this.alignment,               // Align
  this.padding,                 // Padding
  this.color,                   // ColoredBox
  this.decoration,              // DecoratedBox
  this.foregroundDecoration,    // DecoratedBox
  double width,                 // ConstrainedBox
  double height,                // ConstrainedBox
  BoxConstraints constraints,   // ConstrainedBox
  this.margin,                  // Padding
  this.transform,               // Transform
  this.child,
  this.clipBehavior = Clip.none, // ClipPath
})

可以点进去看build方法,这里列出部分代码

Widget current = child;
...
final EdgeInsetsGeometry effectivePadding = _paddingIncludingDecoration;
if (effectivePadding != null)
  current = Padding(padding: effectivePadding, child: current);

if (color != null)
  current = ColoredBox(color: color, child: current);

if (constraints != null)
  current = ConstrainedBox(constraints: constraints, child: current);

if (margin != null)
  current = Padding(padding: margin, child: current);

比如

Padding(padding: padding, child: ColoredBox(color: color, child: child))

Container表示就是下面这样的

Container(color: color, padding: padding, child: child)

不止是Container,还有很多其他组件其实也都是做了一些嵌套而已,这也是声明式UI的一大特色。在Flutter中,Container组件也正是组合优先于继承的实例。

二、属性介绍

1、alignment

对齐方向

需要注意的是Container默认大小是随子组件的,如果设置了这个alignment参数后Container会变成大小会跟随父组件。

2、widthheightconstraints

这三个属性会合成一个约束通过ConstrainedBox嵌套。 它们同时出现的时候widthheight优先。

3、paddingmargin

这两个比较容易用混,我们通过下面一个例子来理解

padding_margin

源码如下

Center(
  child: Container(
    color: Colors.black,
    child: Container(
      color: Colors.red,
      margin: EdgeInsets.all(20),
      padding: EdgeInsets.all(10),
      child: Container(color: Colors.yellow, height: 10, width: 10),
    ),
  ),
)

可以看到红色部分就是padding,在child的外面扩充。 黑色部分就是margin产生的,可以理解为是我虽然只有红色这么大,但是上层你必须给我黑色这么大的空间。

其实build里面的源码嵌套顺序也可以看出来,先设置padding,然后再设置背景颜色和装饰这些,最后再设置margin,相当于最后再在外面套了一个空框。

4、colordecoration

都是设置背景,colordecoration是互斥的,两个只能设置一个, decoration功能更强大,可以设置非常炫酷的效果。

5、foregroundDecoration

前台装饰,先绘制背景和child,最后再绘制 foregroundDecoration,会挡住child

6、transform

矩阵变换,可以是移动、缩放、绕x或y或z轴旋转、或者多个复合的变换。

7、clipBehavior枚举

none:无模式hardEdge:裁剪速度稍快,但容易失真,有锯齿。 antiAlias:裁剪边缘抗锯齿,使得裁剪更平滑,这种模式裁剪速度比antiAliasWithSaveLayer快,但是比hardEdge慢,该模式常用于圆形和弧形之类的形状裁剪。 antiAliasWithSaveLayer:裁剪后具有抗锯齿特性并分配屏幕缓冲区,所有后续操作在缓冲区进行,然后再进行裁剪和合成。

默认是none,这个属性一般情况下用不到。

结束语:Container是非常常用且实用的小组件,很有必要深入理解它。

Copyright © 413132340@qq.com 2020 all right reserved,powered by Gitbook该文章修订时间: 2020-11-30 07:49:29

results matching ""

    No results matching ""