文章目录

  • 布局
  • Flex布局
  • row水平布局
  • 主轴排列方式MainAxisAlignment
  • 交叉轴的排列方式crossAxisAlignment
  • 主轴占用的空间mainAxisSize
  • Column垂直布局
  • Flex布局
  • Expanded
  • Flexible
  • Spacer
  • 缩放布局
  • 堆叠布局
  • Align布局
  • Alignment
  • Alignment.lerp(Alignment a, Alignment b, double t)
  • 偏移量对齐
  • Positioned
  • IndexedStack
  • 容器布局
  • Padding布局
  • 写在后面
  • 参考链接


布局

Flex布局

Flutter中的Flex布局和Web的Css类似。

在Flutter 中用于控制Flex布局的有Row,Column,Expanded,Flexible,Spacer,Flex这些控件。

row水平布局

android flutter 实时布局 flutter各种布局_属性值

属性名

类型

默认值

说明

mainAxisAlignment

MainAxisAlignment

MainAxisAlignment.start

主轴的排列方式

mainAxisSize

MainAxisSize

MainAxisSize.max

主轴占空间的大小

crossAxisAlignment

CrossAxisAlignment

CrossAxisAlignment.center

次轴的排列方式

textDirection

TextDirection

null

确定children在水平方向的摆放顺序

verticalDirection

VerticalDirection

VerticalDirection.down

确定children在垂直方向的摆放顺序

textBaseline

TextBaseline

null

文字基准线对齐

我们首先创建三个大小不一的Container

class LyoutRowDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text("水平布局"),
        ),
        body: Container(
          child: Row(
            children: <Widget>[
              Container(
                height: 100,
                width: 50,
                color: Colors.redAccent,
              ),
              Container(
                height: 50,
                width: 50,
                color: Colors.blueAccent,
              ),
              Container(
                color: Colors.black,
                height: 75,
                width: 75,
              )
            ],
          ),
        ));
  }
}

android flutter 实时布局 flutter各种布局_属性值_02

主轴排列方式MainAxisAlignment

子元素children的排列方式由这两个属性决定textDirection和verticalDirection。textDirection决定水平方向的排列方式TextDirection.ltr从左往右排列(把左当作起始位置),TextDirection.rtl从右往左排列(把右当作起始位置)。verticalDirection时水平方向的排列方式。当值为down(向下排列)时起始位置在顶部。当值为up(向上排列)是起始位置在底部。

  • start (默认值)
    根据textDirection属性排列方向。
    将children放置在主轴的起点
    textDirection属性值为rtl时右图

android flutter 实时布局 flutter各种布局_sed_03

android flutter 实时布局 flutter各种布局_布局_04

  • end
    根据textDirection属性排列方向。
    将children放置在主轴的末尾
    textDirection属性值为rtl时右图

android flutter 实时布局 flutter各种布局_Text_05

android flutter 实时布局 flutter各种布局_属性值_06

  • center
    根据textDirection属性排列方向。
    将children放置在主轴的中心
    textDirection属性值为rtl时右图

android flutter 实时布局 flutter各种布局_属性值_07

android flutter 实时布局 flutter各种布局_sed_08

  • spaceBetween
    根据textDirection属性排列方向。
    将主轴方向上的空白区域均分,使得children之间的空白区域相等,首尾child都靠近首尾,没有间隙
    textDirection属性值为rtl时右图

android flutter 实时布局 flutter各种布局_sed_09

android flutter 实时布局 flutter各种布局_布局_10

  • spaceAround
    根据textDirection属性排列方向。
    将主轴方向上的空白区域均分,使得children之间的空白区域相等,但是首尾空白区域为一半
    textDirection属性值为rtl时右图

android flutter 实时布局 flutter各种布局_Text_11

android flutter 实时布局 flutter各种布局_sed_12

  • spaceEvenly
    根据textDirection属性排列方向
    将主轴方向上的空白区域均分,使得children之间的空白区域相等,包括首尾空白区域
    textDirection属性值为rtl时右图

android flutter 实时布局 flutter各种布局_属性值_13

android flutter 实时布局 flutter各种布局_sed_14

交叉轴的排列方式crossAxisAlignment

都以 mainAxisAlignment: MainAxisAlignment.start为例

  • start
    将子元素在交叉轴上起点对齐。设置verticalDirection为VerticalDirection.up右图。

android flutter 实时布局 flutter各种布局_sed_15

android flutter 实时布局 flutter各种布局_布局_16

  • end
    将子元素在交叉轴上末尾对齐。设置verticalDirection为VerticalDirection.up右图。

android flutter 实时布局 flutter各种布局_属性值_17

android flutter 实时布局 flutter各种布局_sed_18

  • center
    将子元素在交叉轴上居中对齐。设置verticalDirection无改变。

android flutter 实时布局 flutter各种布局_Text_19

  • strentch
    将子元素在交叉轴上拉伸

android flutter 实时布局 flutter各种布局_布局_20

  • baseline
    基准线对其适用于文字,我们首先创建文字的start。必须设置textBaseline属性
Row(
  crossAxisAlignment: CrossAxisAlignment.start,
  textBaseline: TextBaseline.alphabetic,
  children: [
    Text(
      'Flutter',
      style: TextStyle(
        color: Colors.yellow,
        fontSize: 30.0
      ),
    ),
    Text(
      'Flutter',
      style: TextStyle(
          color: Colors.blue,
          fontSize: 20.0
      ),
    ),
  ],
);

android flutter 实时布局 flutter各种布局_布局_21

设置对齐方式为基准线

android flutter 实时布局 flutter各种布局_布局_22

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "水平布局",
      home: Scaffold(
          appBar: AppBar(
            title: Text("水平布局"),
          ),
          body: Container(
            child: Row(
              children: <Widget>[
                Expanded(
                    child: Container(
                  decoration: BoxDecoration(
                    border: Border.all(
                      color: Colors.orange,
                      width: 8.0,
                    ),
                  ),
                  child: Row(
                    children: <Widget>[
                      Expanded(
                          child: RaisedButton(
                              onPressed: () {},
                              color: Colors.red,
                              child: Container(
                                child: Text(
                                  "红色按",
                                ),
                              ))),
                      Container(
                        width: 50,
                          child: RaisedButton(
                        onPressed: () {},
                        color: Colors.green,
                        child: Text(
                          "绿",
                        ),
                      )),
                      Container(
                        width: 70,
                          child: RaisedButton(
                        onPressed: () {},
                        color: Colors.yellow,
                        child: Text(
                          "黄",
                        ),
                      )),
                    ],
                  ),
                )),
                RaisedButton(
                    onPressed: () {},
                    color: Colors.blue,
                    child: Container(
                      child: Text(
                        "蓝色按钮",
                      ),
                    )),
              ],
            ),
          )),
    );
  }
}

橘黄色框和蓝色按钮占据屏幕整个宽度

红色按钮随意扩展 绿色设置50,黄色设置70

android flutter 实时布局 flutter各种布局_Text_23

主轴占用的空间mainAxisSize

mainAxisSize只有两个值一个是min一个是max。默认是max。

当值为min时候。主轴缩紧,变为最小。

如图:即使这时mainAxisAlignment:为MainAxisAlignment.spaceAround。主轴的长度仍为最小状态

android flutter 实时布局 flutter各种布局_布局_24

Column垂直布局

垂直布局与水平布局的属性和方法一致,唯一需要注意的是textDirection(水平排列方式)和verticalDirection(垂直排列方式)

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        title: "垂直布局",
        home: Scaffold(
            appBar: AppBar(title: Text("垂直布局")),
            body: Center(
              child: Column(
			   mainAxisAlignment: MainAxisAlignment.center,
                crossAxisAlignment: CrossAxisAlignment.end,
                children: <Widget>[
                  Text("1",style: TextStyle(fontSize: 100),),
                  Expanded(
                    child: Text("2"),
                  ),
                  Text("33333"),
                  Text("4")
                ],
              ),
            )));
  }
}

为了便于观看我们将1扩大

android flutter 实时布局 flutter各种布局_布局_25

Flex布局

我们查看以下源码便于理解

可以看到RowColumn都继承与Flex

class Row extends Flex 
class Column extends Flex

Row的构造函数可选命名参数(即{}包裹的参数)有8个。

传入父级的super构造函数却有9个,多出了direction: Axis.horizontal

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>[],
  }) : super(
    children: children,
    key: key,
    direction: Axis.horizontal,
    mainAxisAlignment: mainAxisAlignment,
    mainAxisSize: mainAxisSize,
    crossAxisAlignment: crossAxisAlignment,
    textDirection: textDirection,
    verticalDirection: verticalDirection,
    textBaseline: textBaseline,
  );
}

再Flex中属性direction实际上时主轴的方向。且被@required标注。它是必选的。

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,
    List<Widget> children = const <Widget>[],
  }) : assert(direction != null),
       assert(mainAxisAlignment != null),
       assert(mainAxisSize != null),
       assert(crossAxisAlignment != null),
       assert(verticalDirection != null),
       assert(crossAxisAlignment != CrossAxisAlignment.baseline || textBaseline != null),
       super(key: key, children: children);
Expanded

上面的例子我们遇到从未见过的一个widget。很容易就可以看出。Expanded会忽略子元素的大小并强制自动扩展使主轴填充父级可用的空白区域。Expanded必须是Row、Column、Flex的children。

下面两个例子便于更好理解:

//当子元素只有一个Expanded时
class LyoutExpanded extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Expanded"),
      ),
      body: Center(
        child: Container(
          child: Column(
            children: <Widget>[
              Expanded(
                child: Container(
                  color: Colors.blue,
                  width: 100,//这个被忽略掉了
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

android flutter 实时布局 flutter各种布局_Text_26

class LyoutExpanded extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Expanded"),
      ),
      body: Center(
        child: Container(
          height: 50,//填充使主轴扩展至父级高度
          child: Column(
            children: <Widget>[
           Expanded(
                child: Container(
                  color: Colors.blue,
                  height: 100,//
                  width: 100,
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

android flutter 实时布局 flutter各种布局_Text_27

Expanden还有一个属性为flex默认值为1。代表权重。当子元素有多个Expanden。按照权重值占据父级的高度(row时为水平宽度)

<Widget>[
    Expanded(
        flex: 2,
        child: Container(
            color: Colors.blue,
            width: 100,
        ),
    ),
    Expanded(
        child: Container(
            color: Colors.red,
            width: 100,
        ),
    ),
    Expanded(
        child: Container(
            color: Colors.yellow,
            width: 100,
        ),
    ),
],

我们可以看到蓝色的块时红和黄的二倍。

android flutter 实时布局 flutter各种布局_Text_28

Flexible

Flexible组件可以使Row、Column、Flex等子组件在主轴方向有填充可用空间的能力(例如,Row在水平方向,Column在垂直方向),但是它与Expanded组件不同,它不强制子组件填充可用空间。同样Flexible组件必须是Row、Column、Flex等组件的children。

Flexiible 有属性fit当属性值FlexFit.tight时。Flexible和Expanded没有区别。

从源码可以看出Expanded继承与Flexible

且引用 上级构造函数传入fit的值为FlexFit.tight。

class Expanded extends Flexible
//省区其他源码
    

const Expanded({
    Key key,
    int flex = 1,
    @required Widget child,
  }) : super(key: key, flex: flex, fit: FlexFit.tight, child: child);
}

在Column的children中传入。属性fit:为FlexFit.tight,按照权值填充空白区域。

<Widget>[
    Flexible(
        fit: FlexFit.tight,
        child: Container(
            color: Colors.blue,
            height: 100,
            width: 100,
        ),
    ),
    Flexible(
        fit: FlexFit.tight,
        flex: 2,
        child: Container(
            color: Colors.yellow,
            height: 100,
            width: 100,
        ),
    ),
],

android flutter 实时布局 flutter各种布局_属性值_29

一旦fit的值为FlexFit.loose(默认值)先按flex的值分主轴确定占主轴的大小,再按child调整元素的高度。不强制拉伸

例如第一个为tight强制扩展。第二个为loose不强制扩展。

<Widget>[
    Flexible(
        fit: FlexFit.tight,
        child: Container(
            color: Colors.blue,
            height: 100,
            width: 100,
        ),
    ),
    Flexible(
        fit: FlexFit.loose,
        flex: 2,
        child: Container(
            color: Colors.yellow,
            height: 100,
            width: 100,
        ),
    ),
],

android flutter 实时布局 flutter各种布局_属性值_30

因为第二个为loose所以黄颜色的Container高度为100。而蓝色Container的 fit值为 tight,他的大小和上一个例子一致。

Spacer

Spacer创建一个可以调整的空白区域,可用于调整Flex容器(Row或者Colum)中widget之间的间距。

一旦children里面包含了Spacer。mainAxisAlignment的属性值将起不到作用。Spacer已经占据了所有额外的空间,因此没有剩余的空间可以重新分配。

Row(
    mainAxisAlignment: MainAxisAlignment.end,//起不到作用
    children: <Widget>[
        Container(
            height: 100,
            width: 50,
            color: Colors.redAccent,
        ),
        Spacer(),
        Container(
            height: 50,
            width: 50,
            color: Colors.blueAccent,
        ),
        Container(
            color: Colors.black,
            height: 75,
            width: 75,
        )
    ],
),

android flutter 实时布局 flutter各种布局_属性值_31

缩放布局

绝大多数flutter的widget是盒子。可以将他们叠放,堆叠,嵌套。

我们可以层级嵌套盒子,但是如果一个盒子不适合(大小不适合)另一个盒子。该如何解决?

android flutter 实时布局 flutter各种布局_sed_32

为了解决这个问题Flutter提供了FittedBox,这个和移动端的ImageView类似。

它实现的功能是使子元素缩放(fit)或者调整位置(alignment)

  • BoxFit.contain(默认值)等比例扩大或缩小,但内容不会超过容器范围

android flutter 实时布局 flutter各种布局_布局_33

  • BoxFit.cover按照比例逐步扩大至充满容器,内容有能会超过容器范围。当child比例与容器不同时,要么高度溢出容器,要么宽度溢出容器。

android flutter 实时布局 flutter各种布局_Text_34

  • BoxFit.fill不保留比例强制拉伸(缩小)填充容器。

android flutter 实时布局 flutter各种布局_Text_35

  • BoxFit.fitHeight保持比例确保高度在容器中显示完整。

android flutter 实时布局 flutter各种布局_Text_36

  • BoxFit.fitWidth保持比例确保宽度在容器中显示完整。

android flutter 实时布局 flutter各种布局_布局_37

  • BoxFit.none将child对齐在目标框内(默认剧中),并丢弃位于框外的部分,源文件不放大也不缩小。

android flutter 实时布局 flutter各种布局_Text_38

  • BoxFit.scaleDown将child对齐在目标框内(默认剧中),当child大于容器,则与contain一致。如果child小于容器,则与none一致

android flutter 实时布局 flutter各种布局_Text_39

为了便于理解我们可以找一个图片进行测试

class Lyoutfitdemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("data")),
      body: Container(
        height: 250,
        width: 250,
        color: Colors.indigo[200],
        child: FittedBox(
          child: Image.asset('images/fittedbox.png')),
      ),
    );
  }
}
  1. BoxFit.contain

android flutter 实时布局 flutter各种布局_属性值_40

  1. BoxFit.cover

android flutter 实时布局 flutter各种布局_sed_41

  1. BoxFit.fill

android flutter 实时布局 flutter各种布局_属性值_42

  1. BoxFit.fitHeight

android flutter 实时布局 flutter各种布局_sed_43

5.BoxFit.fitWidth

android flutter 实时布局 flutter各种布局_属性值_44

  1. BoxFit.none

android flutter 实时布局 flutter各种布局_sed_45

  1. BoxFit.scaleDown

android flutter 实时布局 flutter各种布局_sed_46


android flutter 实时布局 flutter各种布局_属性值_47

备注:不用创建FittedBox,Image含有属性fit。值效果和FittedBox一致。

堆叠布局

Stack不是Row或者Colum定位的,而是按照特定顺序堆叠。可以使用 Positioned作为Stack的wiget来定位。Stack与web绝对定位布局模型类似。

示例:可以使用层叠布局实现一个 图片渐变效果

import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "渐变状态栏",
      home: Scaffold(
        body: Container(
          height: 400,
          child: Stack(
            fit: StackFit.expand,
            children: <Widget>[
              Image.asset(
                'images/Stack.png',
                fit: BoxFit.cover,
              ),
          
              const DecoratedBox(
                decoration: BoxDecoration(
                  gradient: LinearGradient(
                    begin: Alignment(0.0, -1.0),
                    end: Alignment(0.0, -0.4),
                    colors: <Color>[Color(0x90000000), Color(0x00000000)],
                  ),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

图片渐变效果

android flutter 实时布局 flutter各种布局_布局_48

android flutter 实时布局 flutter各种布局_布局_49

这是两个控件堆叠在一起的例子。当然children也可以出现在任何位置。可以通过两个widget控制。

Align布局

Align为对齐部件,设置child的在父级的(如container、stack等)对齐方式,并根据child的尺寸调整自身的尺寸。

本文的父级容器选用stack

Alignment

其中有这几种属性

topLeft(左上),topCenter(顶部中央),topRight(右上),centerLeft,center,centerRight,bottomLeft,bottomCenter,bottomRight

class LayoutAlignDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text("align部件"),
        ),
        body: Stack(
          children: <Widget>[
            Align(
              alignment: Alignment.topLeft,
              child: Container(
                width: 100,
                height: 100,
                color: Colors.red,
              ),
            ),
          ],
        ));
  }
}

android flutter 实时布局 flutter各种布局_Text_50

Alignment.lerp(Alignment a, Alignment b, double t)

lerp方法有三个参数,前两个参数为Alignment类型,第三个参数为小数。

当t为0时,这个方法返回的值为a。

当t为1时,返回b的值。

当t为0.5时,这个widget位置就位于a和b指定的位置中间。

所以这个t为一个偏移量。指定为a到b之间的偏移。

//在Stack children中添加一个align
Align(
  alignment: Alignment.lerp(Alignment.bottomCenter, Alignment.center,0.5),//位于Alignment.bottomCenter和Alignment.center的中央
  child: Container(
  width: 100,
  height: 100,
  color: Colors.yellow,
   ),
),

android flutter 实时布局 flutter各种布局_属性值_51

偏移量对齐

上面介绍了相对于对其方式a和b的偏移对其。

FractionalOffset 是另外一个偏移方法,它是相对于父部件左上角的偏移。

创建偏移量FractionalOffset (dx,dy)。dx和dy的取值都是0~1。左上的位置为dx和dy都为0。

Align(
  alignment: FractionalOffset(0, 0.5),
  child: Container(
    width: 100,
    height: 100,
    color: Colors.red,
  ),
),

android flutter 实时布局 flutter各种布局_sed_52

另外在源码中:

class FractionalOffset extends Alignment

FractionalOffset继承于Alignment所以Alignment的属性都可以使用,这样我们要使得widget位于左上也可以用使用FractionalOffset.topLeft

class LayoutAlignDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text("align部件"),
        ),
        body: Stack(
          children: <Widget>[
            Align(
              alignment: FractionalOffset(0, 0),
              child: Container(
                width: 100,
                height: 100,
                color: Colors.red,
              ),
            ),
            Align(
              alignment: FractionalOffset(0, 0.5),
              child: Container(
                width: 100,
                height: 100,
                color: Colors.red,
              ),
            ),
            Align(
              alignment: FractionalOffset(0, 1),
              child: Container(
                width: 100,
                height: 100,
                color: Colors.red,
              ),
            ),
            Align(
              alignment: Alignment.lerp(Alignment.bottomCenter, Alignment.center,0.5),
              child: Container(
                width: 100,
                height: 100,
                color: Colors.yellow,
              ),
            ),
            Align(
              alignment: FractionalOffset.topRight,
              child: Container(
                width: 100,
                height: 100,
                color: Colors.yellow,
              ),
            ),
          ],
        ));
  }
}

与之相类似的还有Alignment(dx, dy),以父级容器的中心为坐标系原点。dx的取值范围为-11,dy的取值范围为-11。设置子元素的位置。

Positioned

Positioned 部件可以控制Stack中子元素的位置。Positioned 与Align不同的是Position必须是Stack的Children。

Position有topbottomleftrightheightwidth

topbottomleftright这些量都是与某一边界的距离。

当一个大小高度和长度固定容器一旦我们确定其水平方向和垂直方向上各一个量。其位置是固定的。

部分代码

Stack(
    children: <Widget>[
        Positioned(
            top: 100,
            right: 100,
            width: 100,
            height: 100,
            child: Container(
                color: Colors.red,
            ),
        ),
    ],
)

android flutter 实时布局 flutter各种布局_sed_53

源码分析

const Positioned({
    Key key,
    this.left,
    this.top,
    this.right,
    this.bottom,
    this.width,
    this.height,
    @required Widget child,
  }) : assert(left == null || right == null || width == null),
       assert(top == null || bottom == null || height == null),
       super(key: key, child: child);

在水平方向上如果assert(false)会抛出错误

而括号里的值为left == null || right == null || width == null

left ,right ,width 至少有一个值为null这个程序才不会报错。

也就是说当width未指定(为空)使left和right是可以同时存在的。这时的容器的宽度会以据边界的距离(left和right)自动调整。

Stack(
    children: <Widget>[
        Positioned(
            top: 100,
            right: 100,
            left: 100,
            // width: 100,
            height: 100,
            child: Container(
                color: Colors.red,
            ),
        ),
    ],
)

android flutter 实时布局 flutter各种布局_布局_54

IndexedStack

IndexedStack继承于Stack

class IndexedStack extends Stack

他和Stack不同的是有一个index的属性,表示只显示第几个元素。

IndexedStack(
    index: 1,//只显示第二个
    children: <Widget>[
        Positioned(
            top: 100,
            right: 100,
            left: 100,
            height: 100,
            child: Container(
                color: Colors.red,
            ),
        ),  
        Positioned(
            top: 500,
            right: 100,
            left: 100,
            height: 100,
            child: Container(
                color: Colors.red,
            ),
        ),
    ],
)

android flutter 实时布局 flutter各种布局_Text_55

容器布局

Container可以创建一个矩形元素。可以用BoxDecoration进行装饰。背景,边框,阴影。

class LyoutContainerdemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Container容器"),
      ),
      body: Container(
        height: 200,
        width: 200,
        child: Text("这是一个Container容器"),
        decoration: BoxDecoration(
          color: Colors.red[200],
          // shape: BoxShape.circle, //形状
          border: Border.all(width: 10.0),
          boxShadow: [
            BoxShadow(
              offset: Offset(0.0, 100.0), //模糊偏移量
              color: Color.fromRGBO(16, 20, 188, 1.0), //颜色
              blurRadius: 10, //模糊
              spreadRadius: -9.0, //在应用模糊之前阴影的膨胀量
            ),
          ],
        ),
      ),
    );
  }
}

android flutter 实时布局 flutter各种布局_属性值_56

为了演示功能,这个图片效果做的比较夸张。

附上一个好看的效果

android flutter 实时布局 flutter各种布局_布局_57

相似于Css的盒子布局,我们也可以通过Margin给盒子设置外边距。

Container(
    margin: EdgeInsets.all(50.0),//外边距50.0
    height: 200,
    width: 200,
    decoration: BoxDecoration(
        color: Colors.red[600],
        border: Border.all(width: 2.0),
        boxShadow: [
            BoxShadow(
                offset: Offset(2.0, 9.0), //偏移量
                color: Colors.red[200], //颜色
                blurRadius: 10, //模糊
                spreadRadius: -1.0, //在应用模糊之前阴影的膨胀量
            ),
        ],
    ),
),

android flutter 实时布局 flutter各种布局_属性值_58

Padding布局

用于处理容器与子元素之间的距离。与Padding对应的是margin属性。margin用于处理与其他组件之间的距离。Padding部件和容器内的pading属性的效果实际上是一致的,当同时出现,真实的padding将是两者相加。

class LayoutPaddingDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Padding 布局"),
      ),
      body: Container(
        padding: EdgeInsets.all(20.0),//#1这两处的属性效果是一致的
        decoration: BoxDecoration(
            color: Colors.yellow,
            border: Border.all(color: Colors.white, width: 8.0)),//白色边框
        child: Padding(
          child: Container(
            decoration: BoxDecoration(
            color: Colors.red,
            border: Border.all(color: Colors.white, width: 8.0)),//白色边框
          ),
          padding: EdgeInsets.all(10.0),//#1这两处的属性效果是一致的
        ),
      ),
    );
  }
}

android flutter 实时布局 flutter各种布局_布局_59

写在后面

Flutter中涉及到布局的Widget有30多种,一样的效果的ui,实现的途径有很多中。本篇就重点涉及几个常用的部件。