容器顾名思义是可以容纳其他 Widget 的,这一节我们学习Padding、DecoratedBox和ConstrainedBox。

一、Padding

在 Android 开发中我们给控件会设置内边距和外边距,也就是 padding 和 margin,当然父控件如果设置了 padding 实际上对子控件也会造成影响。Flutter 中 Padding 可以给其子节点添加填充。

const Padding({
    Key key,
    @required this.padding,
    Widget child,
  })

padding ---- EdgeInsetsGeometry 类型,为子节点插入填充

EdgeInsetsGeometry 是一个抽象类,我们一般使用其子类 EdgeInsets

class EdgeInsets extends EdgeInsetsGeometry {
  /// 分别指定四个方向的填充。
  const EdgeInsets.fromLTRB(this.left, this.top, this.right, this.bottom);

  /// 所有方向均使用相同数值的填充。
  const EdgeInsets.all(double value)
    : left = value,
      top = value,
      right = value,
      bottom = value;

  /// 可以设置具体某个方向的填充。
  const EdgeInsets.only({
    this.left = 0.0,
    this.top = 0.0,
    this.right = 0.0,
    this.bottom = 0.0,
  });

  /// 设置对称方向的填充。
  const EdgeInsets.symmetric({
    double vertical = 0.0,
    double horizontal = 0.0,
  }) : left = horizontal,
       top = vertical,
       right = horizontal,
       bottom = vertical;
  ......
}

下面我们给 Padding 的 child 设置一个 Text 看一下效果。效果是 Text 周围预留 8px。

Padding(
  padding: const EdgeInsets.all(8.0),
  child: Text("观察如何影响子控件,观察如何影响子控件,观察如何影响子控件")
),

android rect 填充颜色 安卓容器填充_Text

二、ConstrainedBox

Constrained 约束的意思,Box 盒子,所以这个容器实际上就是一个带有限制的框子!

ConstrainedBox({
    Key key,
    @required this.constraints,
    Widget child,
  })

constraints ---- 对 child 施加的附加约束。

const BoxConstraints({
    this.minWidth = 0.0,
    this.maxWidth = double.infinity,
    this.minHeight = 0.0,
    this.maxHeight = double.infinity,
  })

这些属性非常好理解,最小宽度、最大宽度、最小高度和最大高度。另外当设置为 double.infinity 代表无限大。

接下来我们对一个 Text 施加限制,观察 ConstrainedBox Widget 的效果。我们设置了最大宽度为 100,无法在一行内容纳所有的文字,要换行几次才行。

ConstrainedBox(
  constraints: BoxConstraints(maxWidth: 100),
  child: Text("观察如何影响子控件,观察如何影响子控件,观察如何影响子控件"))

android rect 填充颜色 安卓容器填充_ide_02

三、DecoratedBox

可装饰的 Box,可以在其子 Widget 绘制前(或后)绘制一些装饰,如背景和边框等。

const DecoratedBox({
    Key key,
    @required this.decoration,
    this.position = DecorationPosition.background,
    Widget child,
  })

decoration ---- 代表将要绘制的装饰,它的类型为 Decoration,我们一般使用它的子类 BoxDecoration。

position ---- 在哪里画框装饰。

enum DecorationPosition {
  /// 子 Widget 之后
  background,

  /// 子 Widget 之前
  foreground,
}

下面来详细学习 BoxDecoration。

const BoxDecoration({
    this.color,
    this.image,
    this.border,
    this.borderRadius,
    this.boxShadow,
    this.gradient,
    this.backgroundBlendMode,
    this.shape = BoxShape.rectangle,
  })

color ---- 背景颜色

image ---- 背景图片

border ---- 边框,在背景 [color],[gradient] 或 [image] 上方绘制边框,依据 [shape] 和 [borderRadius] 绘制。

borderRadius ---- 边框圆角

boxShadow ---- 阴影

gradient ---- 渐变

backgroundBlendMode ---- 背景混合模式

shape ---- 背景形状

再来看 border ,它是一个 BoxBorder 类型,抽象类,我们一般使用其子类 Border。

const Border({
    this.top = BorderSide.none,
    this.right = BorderSide.none,
    this.bottom = BorderSide.none,
    this.left = BorderSide.none,
  })

这不难看出是是个方向都可以控制,另外它们的类型是 BorderSide。

const BorderSide({
    this.color = const Color(0xFF000000),
    this.width = 1.0,
    this.style = BorderStyle.solid,
  })

color ---- 颜色

width ---- 宽度

style ---- 样式

enum BorderStyle {
  none,
  /// 以实线绘制边框。
  solid,
}

borderRadius 是 BorderRadiusGeometry 类型,我们一般使用其子类 BorderRadius。

/// 边框半径均为 [radius]。
  const BorderRadius.all(Radius radius) : this.only(
    topLeft: radius,
    topRight: radius,
    bottomLeft: radius,
    bottomRight: radius,
  );

  /// 创建垂直对称的边框半径,其中矩形的顶部和底部的半径相同。
  const BorderRadius.vertical({
    Radius top = Radius.zero,
    Radius bottom = Radius.zero,
  }) : this.only(
    topLeft: top,
    topRight: top,
    bottomLeft: bottom,
    bottomRight: bottom,
  );

  /// 创建水平对称的边框半径,其中矩形的左侧和右侧具有相同的半径。
  const BorderRadius.horizontal({
    Radius left = Radius.zero,
    Radius right = Radius.zero,
  }) : this.only(
    topLeft: left,
    topRight: right,
    bottomLeft: left,
    bottomRight: right,
  );

  /// 仅使用给定的非零值创建边框半径,其他角将是直角。
  const BorderRadius.only({
    this.topLeft = Radius.zero,
    this.topRight = Radius.zero,
    this.bottomLeft = Radius.zero,
    this.bottomRight = Radius.zero,
  });

boxShadow ---- 在框后面投射的阴影列表,其 list 内元素为 BoxShadow 类型。

const BoxShadow({
    Color color = const Color(0xFF000000),
    Offset offset = Offset.zero,
    double blurRadius = 0.0,
    this.spreadRadius = 0.0,
  })

color 和 offset 很容易理解,即为颜色和偏移。

创建一个偏移量。 第一个参数设置[dx],水平分量,第二个参数[dy],垂直分量。

const Offset(double dx, double dy)

blurRadius ---- 模糊半径

spreadRadius ---- 在应用模糊效果之前,应先对 Box 扩展,设置宽展半径。

gradient 是 Gradient 类型,2D渐变,也就是填充 Box 时要使用的渐变。我们一般使用其子类 LinearGradient、RadialGradient 和 SweepGradient。

shape 是 BoxShape 类型。

enum BoxShape {
  /// 矩形
  rectangle,
  /// 圆形
  circle,
}

来看一个使用 DecoratedBox 的例子。

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: ContainerRoute(),
    );
  }
}

class ContainerRoute extends StatefulWidget {
  @override
  _ContainerRouteState createState() => new _ContainerRouteState();
}

class _ContainerRouteState extends State<ContainerRoute> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Container"),
      ),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.start,
        crossAxisAlignment: CrossAxisAlignment.start,
        children: <Widget>[
          Padding(
              padding: const EdgeInsets.all(8.0),
              child: Text("观察如何影响子控件,观察如何影响子控件,观察如何影响子控件")),
          ConstrainedBox(
              constraints: BoxConstraints(maxWidth: 100),
              child: Text("观察如何影响子控件,观察如何影响子控件,观察如何影响子控件")),
          Padding(
            padding: const EdgeInsets.all(8.0),
            child: DecoratedBox(
              decoration: BoxDecoration(
                gradient: LinearGradient(
                    colors: [Colors.red[600], Colors.green[600]]),
                borderRadius: BorderRadius.all(Radius.circular(6)),
                boxShadow: [
                  //阴影
                  BoxShadow(
                      color: Colors.grey,
                      offset: Offset(3.0, 3.0),
                      blurRadius: 4.0,
                      spreadRadius: 2.0),
                ],
              ),
              child: Padding(
                padding: const EdgeInsets.all(8.0),
                child: Text("观察如何影响子控件,观察如何影响子控件,观察如何影响子控件"),
              ),
            ),
          )
        ],
      ),
    );
  }
}

android rect 填充颜色 安卓容器填充_ide_03