天天看點

Flutter布局——Flex、FittedBox、Stack、Container

Flex布局

Flutter中的Flex布局和Web的CSS中的Flex布局類似。

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

row水準布局

Flutter布局——Flex、FittedBox、Stack、Container
屬性名 類型 預設值 說明
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,
              )
            ],
          ),
        ));
  }
}
複制代碼      
Flutter布局——Flex、FittedBox、Stack、Container

主軸排列方式MainAxisAlignment

子元素children的排列方式由這兩個屬性決定textDirection和verticalDirection。textDirection決定水準方向的排列方式​

​TextDirection.ltr​

​​從左往右排列(把左當作起始位置),​

​TextDirection.rtl​

​從右往左排列(把右當作起始位置)。verticalDirection時水準方向的排列方式。當值為down(向下排列)時起始位置在頂部。當值為up(向上排列)是起始位置在底部。

  • start (預設值) 根據textDirection屬性排列方向。

    将children放置在主軸的起點

    textDirection屬性值為rtl時右圖

Flutter布局——Flex、FittedBox、Stack、Container
Flutter布局——Flex、FittedBox、Stack、Container
  • end

    根據textDirection屬性排列方向。

    将children放置在主軸的末尾

    textDirection屬性值為rtl時右圖

Flutter布局——Flex、FittedBox、Stack、Container
Flutter布局——Flex、FittedBox、Stack、Container
  • center

    根據textDirection屬性排列方向。

    将children放置在主軸的中心

    textDirection屬性值為rtl時右圖

Flutter布局——Flex、FittedBox、Stack、Container
Flutter布局——Flex、FittedBox、Stack、Container
  • spaceBetween

    根據textDirection屬性排列方向。

    将主軸方向上的空白區域均分,使得children之間的空白區域相等,首尾child都靠近首尾,沒有間隙

    textDirection屬性值為rtl時右圖

Flutter布局——Flex、FittedBox、Stack、Container
Flutter布局——Flex、FittedBox、Stack、Container
  • spaceAround

    根據textDirection屬性排列方向。

    将主軸方向上的空白區域均分,使得children之間的空白區域相等,但是首尾空白區域為一半

    textDirection屬性值為rtl時右圖

Flutter布局——Flex、FittedBox、Stack、Container
Flutter布局——Flex、FittedBox、Stack、Container
  • spaceEvenly

    根據textDirection屬性排列方向

    将主軸方向上的空白區域均分,使得children之間的空白區域相等,包括首尾空白區域

    textDirection屬性值為rtl時右圖

Flutter布局——Flex、FittedBox、Stack、Container
Flutter布局——Flex、FittedBox、Stack、Container

交叉軸的排列方式crossAxisAlignment

都以 ​

​mainAxisAlignment: MainAxisAlignment.start​

​為例

  • start

    将子元素在交叉軸上起點對齊。設定verticalDirection為VerticalDirection.up右圖。

Flutter布局——Flex、FittedBox、Stack、Container
Flutter布局——Flex、FittedBox、Stack、Container
  • end

    将子元素在交叉軸上末尾對齊。設定verticalDirection為VerticalDirection.up右圖。

Flutter布局——Flex、FittedBox、Stack、Container
Flutter布局——Flex、FittedBox、Stack、Container
  • center

    将子元素在交叉軸上居中對齊。設定verticalDirection無改變。

Flutter布局——Flex、FittedBox、Stack、Container
  • strentch

    将子元素在交叉軸上拉伸

Flutter布局——Flex、FittedBox、Stack、Container
  • baseline

    基準線對其适用于文字,我們首先建立文字的start。使用baseline。必須設定textBaseline屬性。不同文字的文字基準線。主要是字母文字(如:英語)和表意文字(如:漢語)的基準線是不同的。必須告訴Flutter你使用的文字。

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
      ),
    ),
  ],
);
複制代碼      
Flutter布局——Flex、FittedBox、Stack、Container

設定對齊方式為基準線

Flutter布局——Flex、FittedBox、Stack、Container

主軸占用的空間mainAxisSize

mainAxisSize隻有兩個值一個是min一個是max。預設是max。

當值為min時候。主軸縮緊,變為最小。

如圖:即使這時mainAxisAlignment:為MainAxisAlignment.spaceAround。主軸的長度仍為最小狀态

Flutter布局——Flex、FittedBox、Stack、Container

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擴大

Flutter布局——Flex、FittedBox、Stack、Container

Flex布局

我們檢視以下源碼便于了解

可以看到​

​Row​

​​和​

​Column​

​​都繼承與​

​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,//這個被忽略掉了
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

複制代碼      
Flutter布局——Flex、FittedBox、Stack、Container
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,
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}
複制代碼      
Flutter布局——Flex、FittedBox、Stack、Container

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,
        ),
    ),
],
複制代碼      

我們可以看到藍色的塊時紅和黃的二倍。

Flutter布局——Flex、FittedBox、Stack、Container

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,
        ),
    ),
],
複制代碼      
Flutter布局——Flex、FittedBox、Stack、Container

一旦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,
        ),
    ),
],
複制代碼      
Flutter布局——Flex、FittedBox、Stack、Container

因為第二個為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,
        )
    ],
),
複制代碼      
Flutter布局——Flex、FittedBox、Stack、Container

縮放布局

絕大多數flutter的widget是盒子。可以将他們疊放,堆疊,嵌套。

我們可以層級嵌套盒子,但是如果一個盒子不适合(大小不适合)另一個盒子。該如何解決?

Flutter布局——Flex、FittedBox、Stack、Container

為了解決這個問題Flutter提供了FittedBox,這個和移動端的ImageView類似。

它實作的功能是使子元素縮放(fit)或者調整位置(alignment)

  • BoxFit.contain(預設值)等比例擴大或縮小,但内容不會超過容器範圍
Flutter布局——Flex、FittedBox、Stack、Container
  • BoxFit.cover按照比例逐漸擴大至充滿容器,内容有能會超過容器範圍。當child比例與容器不同時,要麼高度溢出容器,要麼寬度溢出容器。
Flutter布局——Flex、FittedBox、Stack、Container
  • BoxFit.fill不保留比例強制拉伸(縮小)填充容器。
Flutter布局——Flex、FittedBox、Stack、Container
  • BoxFit.fitHeight保持比例確定高度在容器中顯示完整。
Flutter布局——Flex、FittedBox、Stack、Container
  • BoxFit.fitWidth保持比例確定寬度在容器中顯示完整。
Flutter布局——Flex、FittedBox、Stack、Container
  • BoxFit.none将child對齊在目标框内(預設劇中),并丢棄位于框外的部分,源檔案不放大也不縮小。
Flutter布局——Flex、FittedBox、Stack、Container
  • BoxFit.scaleDown将child對齊在目标框内(預設劇中),當child大于容器,則與contain一緻。如果child小于容器,則與none一緻
Flutter布局——Flex、FittedBox、Stack、Container

為了便于了解我們可以找一個圖檔進行測試

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
Flutter布局——Flex、FittedBox、Stack、Container
  1. BoxFit.cover
Flutter布局——Flex、FittedBox、Stack、Container
  1. BoxFit.fill
Flutter布局——Flex、FittedBox、Stack、Container
  1. BoxFit.fitHeight
Flutter布局——Flex、FittedBox、Stack、Container

5.BoxFit.fitWidth

Flutter布局——Flex、FittedBox、Stack、Container
  1. BoxFit.none
Flutter布局——Flex、FittedBox、Stack、Container
  1. BoxFit.scaleDown
Flutter布局——Flex、FittedBox、Stack、Container
Flutter布局——Flex、FittedBox、Stack、Container
備注:不用建立FittedBox,Image含有屬性fit。值效果和FittedBox一緻。

堆疊布局

Stack與web絕對定位布局模型類似。Stack不是按行或者列來布局的,而是按照特定順序和位置堆疊。可以使用 ​

​Positioned​

​​和​

​Align​

​作為Stack的的定位。

示例:使用層疊布局實作一個 圖檔漸變效果

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)],
                  ),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}
複制代碼      

圖檔漸變效果

Flutter布局——Flex、FittedBox、Stack、Container
Flutter布局——Flex、FittedBox、Stack、Container

這是兩個控件堆疊在一起的例子。當然子部件可以出現在父級内的任何位置。通過兩種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,
              ),
            ),
          ],
        ));
  }
}
複制代碼      
Flutter布局——Flex、FittedBox、Stack、Container

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,
   ),
),
複制代碼      
Flutter布局——Flex、FittedBox、Stack、Container

偏移量對齊

上面介紹了相對于對其方式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,
  ),
),
複制代碼      
Flutter布局——Flex、FittedBox、Stack、Container

另外在源碼中:

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的取值範圍為-1~1,dy的取值範圍為-1~1。設定子元素的位置。

Positioned

Positioned 部件可以控制​

​Stack​

​中子元素的位置。Positioned 與Align不同的是Position必須是Stack的Children。

Position有​

​top​

​​、​

​bottom​

​​、​

​left​

​​、​

​right​

​​、​

​height​

​​,​

​width​

​。

​top​

​​、​

​bottom​

​​、​

​left​

​​、​

​right​

​這些量都是子元素邊界與父級某一邊界的距離。

也就是說當一個高度和長度固定容器,一旦我們确定left或right的一個量和bottom或top的一個量,其位置就可以确定。

部分代碼

Stack(
    children: <Widget>[
        Positioned(
            top: 100,
            right: 100,
            width: 100,
            height: 100,
            child: Container(
                color: Colors.red,
            ),
        ),
    ],
)
複制代碼      
Flutter布局——Flex、FittedBox、Stack、Container

源碼分析

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,
            ),
        ),
    ],
)
複制代碼      
Flutter布局——Flex、FittedBox、Stack、Container

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,
            ),
        ),
    ],
)
複制代碼      
Flutter布局——Flex、FittedBox、Stack、Container

容器布局

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, //在應用模糊之前陰影的膨脹量
            ),
          ],
        ),
      ),
    );
  }
}

複制代碼      
Flutter布局——Flex、FittedBox、Stack、Container

為了示範功能,這個圖檔效果做的比較誇張。

附上一個好看的效果

Flutter布局——Flex、FittedBox、Stack、Container

相似于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, //在應用模糊之前陰影的膨脹量
            ),
        ],
    ),
),
複制代碼      
Flutter布局——Flex、FittedBox、Stack、Container

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這兩處的屬性效果是一緻的
        ),
      ),
    );
  }
}

複制代碼      
Flutter布局——Flex、FittedBox、Stack、Container

寫在後面

Flutter中涉及到布局的Widget有30多種,一樣的效果的ui,實作的途徑有很多中。本篇就重點涉及幾個常用的部件。

參考連結

​​youtu.be/T4Uehk3_wlY​​