Container

Container是我们要介绍的最后一个容器类widget,它本身不对应具体的RenderObject,它是DecoratedBox、ConstrainedBox、Transform、Padding、Align等widget的一个组合widget。所以我们只需通过一个Container可以实现同时需要装饰、变换、限制的场景。下面是Container的定义:

  1. Container({
  2. this.alignment,
  3. this.padding, //容器内补白,属于decoration的装饰范围
  4. Color color, // 背景色
  5. Decoration decoration, // 背景装饰
  6. Decoration foregroundDecoration, //前景装饰
  7. double width,//容器的宽度
  8. double height, //容器的高度
  9. BoxConstraints constraints, //容器大小的限制条件
  10. this.margin,//容器外补白,不属于decoration的装饰范围
  11. this.transform, //变换
  12. this.child,
  13. })

大多说属性在介绍其它容器时都已经介绍过了,不再赘述,但有两点需要说明:

  • 容器的大小可以通过widthheight属性来指定,也可以通过constraints来指定,如果同时存在时,widthheight优先。实际上Container内部会根据widthheight来生成一个constraints
  • colordecoration是互斥的,实际上,当指定color时,Container内会自动创建一个decoration。

实例

我们通过Container来实现如下的卡片:

image-20180910205356331

代码:

  1. Container(
  2. margin: EdgeInsets.only(top: 50.0, left: 120.0), //容器外补白
  3. constraints: BoxConstraints.tightFor(width: 200.0, height: 150.0), //卡片大小
  4. decoration: BoxDecoration(//背景装饰
  5. gradient: RadialGradient( //背景径向渐变
  6. colors: [Colors.red, Colors.orange],
  7. center: Alignment.topLeft,
  8. radius: .98
  9. ),
  10. boxShadow: [ //卡片阴影
  11. BoxShadow(
  12. color: Colors.black54,
  13. offset: Offset(2.0, 2.0),
  14. blurRadius: 4.0
  15. )
  16. ]
  17. ),
  18. transform: Matrix4.rotationZ(.2), //卡片倾斜变换
  19. alignment: Alignment.center, //卡片内文字居中
  20. child: Text( //卡片文字
  21. "5.20", style: TextStyle(color: Colors.white, fontSize: 40.0),
  22. ),
  23. );

可以看到Container通过组合多种widget来实现复杂强大的功能,在Flutter中,这也正是组合优先于继承的实例。

Padding和Margin

接下来我们看看Container的marginpadding属性的区别:

  1. ...
  2. Container(
  3. margin: EdgeInsets.all(20.0), //容器外补白
  4. color: Colors.orange,
  5. child: Text("Hello world!"),
  6. ),
  7. Container(
  8. padding: EdgeInsets.all(20.0), //容器内补白
  9. color: Colors.orange,
  10. child: Text("Hello world!"),
  11. ),
  12. ...

image-20180911094807143

可以发现,直观的感觉就是margin的补白是在容器外部,而padding的补白是在容器内部,读者需要记住这个差异。事实上,Container内marginpadding都是通过Padding widget来实现的,上面的示例代码实际上等价于:

  1. ...
  2. Padding(
  3. padding: EdgeInsets.all(20.0),
  4. child: DecoratedBox(
  5. decoration: BoxDecoration(color: Colors.orange),
  6. child: Text("Hello world!"),
  7. ),
  8. ),
  9. DecoratedBox(
  10. decoration: BoxDecoration(color: Colors.orange),
  11. child: Padding(
  12. padding: const EdgeInsets.all(20.0),
  13. child: Text("Hello world!"),
  14. ),
  15. ),
  16. ...