blog icon indicating copy to clipboard operation
blog copied to clipboard

[译] Flutter: 图解 Container 部件

Open SunshowerC opened this issue 6 years ago • 1 comments


  • Container 简介
  • 布局
    • 没有子组件
    • 有子组件
    • alignment 对齐(Alignment)
      • 位置:居中
      • 位置:右下角
      • 位置常量
    • alignment 对齐(FractionalOffset)
    • constraints (大小约束)
      • 容器有子部件
      • 容器可以被子部件撑开
      • 容器撑开到最大
      • 定宽设置
    • margin 外边距
      • 四边都有 margin
      • 对称 margin (EdgeInsets.symmetric)
      • 位置 margin (EdgeInsets.fromLTRB)
      • 指定一边 margin
    • Padding 内填充
    • Decoration 属性
    • ForegroundDecoration 属性
    • Transform 属性

Container 简介

Container部件用于包含子部件,可以应用某些样式属性。,具备了常见的绘画,定位和大小调整等功能。(相当于 HTML 中的 div)

如果Container小部件没有子节点,它将尽可能大地自动填充屏幕上的给定区域。

布局

由于Container结合了许多其他小部件,每个小部件都有自己的布局行为,因此Container的布局行为有点复杂。

没有子组件

Container尽可能大

Center(
  child: Container(
    color: Colors.green,
  ),
);

有子组件

Container 适应子组件的大小

Center(
  child: Container(
    color: Colors.green,
    child: Text("Flutter CheatSheet."),
  ),
);

alignment 对齐(Alignment)

alignment: Alignment(x, y) 属性接受两个参数:x 和 y。

x, y 坐标轴如下

注意:默认情况下,alignment 中 x 值可以大于 1 或者 小于 -1,但除非设置了 constraints 限制, 否则 y 值设置只在 -1 <= y <= 1 范围内有效

位置:居中

Center(
  child: Container(
    color: Color.fromARGB(255, 66, 165, 245),
    child: new Text("Flutter Cheatsheet",
      style: TextStyle(
        fontSize: 10.0
      ),
    ),
    //  `Container` 的中心。
    alignment: Alignment(0.0, 0.0),
  ),
);

位置:右下角

  alignment: Alignment(1.0, 1.0),

位置常量

Alignment.bottomCenter == Alignment(0.0, 1.0)
Alignment.bottomLeft == Alignment(-1.0, 1.0)
Alignment.bottomRight == Alignment(1.0, 1.0)
Alignment.center ==  Alignment(0.0, 0.0)
Alignment.centerLeft == Alignment(-1.0, 0.0)
Alignment.centerRight == Alignment(1.0, 0.0)
Alignment.topCenter == Alignment(0.0, -1.0)
Alignment.topLeft == Alignment(-1.0, -1.0)
Alignment.topRight == Alignment(1.0, -1.0)

alignment 对齐(FractionalOffset)

FractionalOffset 和 Alignment 类似,都能表达位置。

两个方式之间的区别在于它们用于表示位置的坐标系。

不同于 Alignment 以 中心为原点, FractionalOffset 是以左上角为原点的,如下图:

constraints (大小约束)

constraints 属性用于指定容器可以占据的大小和空间。一般值为 BoxConstraint

基本可以使用简单的 BoxConstraint 构建大多数的部件和UI。

BoxConstraint 只有 4 个属性

  • minWidth: 默认为 0,0 不代表宽度为0,而是尽可能小,代表宽度完全由子部件撑开
  • minHeighth: 同上
  • maxWidth:默认 double.infinity,撑到最大
  • maxHeight:同上。

注意: 当没有 child 时,选择 max 的值
当有 child 时,选择 min 值
当设置了 alignment 时,无论有没有 child 值,都选择 max 值。

容器有子部件

因为有 child,所以会渲染 min 值的容器。

Center(
  child: Container(
    color: Color.fromARGB(255, 66, 165, 245),
    alignment: AlignmentDirectional(0.0, 0.0),
    child: Container(
      color: Colors.green,
      child: Text("Flutter"),
      constraints: BoxConstraints(
          maxHeight: 300.0,
          maxWidth: 200.0,
          minWidth: 150.0,
          minHeight: 150.0
      ),
    ),
  ),
);

容器可以被子部件撑开

Center(
  child: Container(
    color: Color.fromARGB(255, 66, 165, 245),
    alignment: AlignmentDirectional(0.0, 0.0),
    child: Container(
      color: Colors.green,
      child: Text("Flutter Cheatsheet Flutter Cheatsheet"),
      constraints: BoxConstraints(
          maxHeight: 300.0,
          maxWidth: 200.0,
          minWidth: 150.0,
          minHeight: 150.0
      ),
    ),
  ),
);

子部件长文本,会撑开容器,最大能够撑开到 max-width 和 max-height。再大就会溢出

容器撑开到最大

上面说过,如果存在 child 子部件,容器就会限制在 min 值, 那么要让存在 child 子部件的情况下让容器扩展到最大,也是有办法的。

Center(
  child: Container(
    color: Color.fromARGB(255, 66, 165, 245),
    alignment: AlignmentDirectional(0.0, 0.0),
    child: Container(
      color: Colors.green,
      child: Text("Flutter"),
      constraints: BoxConstraints.expand(),
      // 等价于
      /*
      constraints: BoxConstraints(
        minWidth: double.infinity,
        minHeight: double.infinity
      ),
      */
    ),
  ),
);

定宽设置

上面提到的都是 弹性容器,下面介绍下,通过BoxConstraints.expand(width, height) 可以设置定宽容器:

Center(
  child: Container(
    color: Color.fromARGB(255, 66, 165, 245),
    alignment: AlignmentDirectional(0.0, 0.0),
    child: Container(
      color: Colors.green,
      child: Text("Flutter"),
      constraints: BoxConstraints.expand(
        width: 350.0,
        height: 400.0
      ),
    ),
  ),
);

margin 外边距

margin 是外边距,和 CSS 的一样。

四边都有 margin

Center(
  child: Container(
    color: Color.fromARGB(255, 66, 165, 245),
    alignment: AlignmentDirectional(0.0, 0.0),
    child: Container(
      color: Colors.green,
      margin: new EdgeInsets.all(20.0),
      // 相当于 CSS 的 margin: 20px;
    ),
  ),
);

对称 margin (EdgeInsets.symmetric)

margin : EdgeInsets.symmetric(
  vertical: 20,
  horizontal: 50
)
// 相当于 CSS 的 margin: 20px 50px; 

位置 margin (EdgeInsets.fromLTRB)

EdgeInsets.fromLTRB(left, top, right, bottom)

margin: new EdgeInsets.fromLTRB(20.0, 30.0, 40.0, 50.0),
// 相当于 CSS 的 margin: 30px 40px 50px 20px;

注意,CSS 的 margin 的顺序是上右下左,而EdgeInsets.fromLTRB 的顺序是 左上右下,千万不要弄混

指定一边 margin

EdgeInsets.only({double left: 0.0, double top: 0.0, double right: 0.0, double bottom: 0.0})

margin: new EdgeInsets.only(
    left: 20.0,
    top: 50.0
),
// 相当于 margin-left: 20px; margin-top: 50px;

Padding 内填充

Center(
  child: Container(
    color: Color.fromARGB(255, 66, 165, 245),
    alignment: AlignmentDirectional(0.0, 0.0),
    child: Container(
      color: Colors.green,
      padding: EdgeInsets.all(20.0),
      // 相当于 CSS 的 margin: 20px;
    ),
  ),
);

使用方式同 margin,不再多说

Decoration 属性

修饰背景。 值可以是:

  • BoxDecoration 类
  • FlutterLogoDecoration 类
  • ShapeDecoration 类
  • UnderlineTabIndicator 类

原作者将在另外的文章中讨论上述类

PS: 前面提到了 margin, padding,但是 Container 是 没有 border 属性的哦,要实现 border,需要在 decoration 属性中进行设置。

Center(
  child: Container(
    color: Color.fromARGB(255, 66, 165, 245),
    alignment: AlignmentDirectional(0.0, 0.0),
    child: Container(
      color: Colors.green,
      decoration: BoxDecoration(
          border: Border.all(width: 2, color: Color(0xffaaaaaa))
      )
      // 相当于 CSS 的 border: 2px solid #aaaaaa;
    ),
  ),
);

ForegroundDecoration 属性

修饰前景

同上。

Transform 属性

值为 Matrix 类

Center(
  child: Container(
    color: Color.fromARGB(255, 66, 165, 245),
    alignment: AlignmentDirectional(0.0, 0.0),
    child: Container(
      padding: new EdgeInsets.all(40.0),
      color: Colors.green,
      child: Text("Flutter Cheatsheet"),
      transform: new Matrix4.rotationZ(0.5)
    ),
  ),
);

原作者将在另外的文章中讨论 Matrix

SunshowerC avatar Jan 15 '19 16:01 SunshowerC

nice!

myxiaojiang avatar Jan 17 '19 07:01 myxiaojiang