天天看點

Flutter程式設計之BoxDecoration用法詳解

Widget

的裝飾,使其改變其顯示形式。

Container

decoration

BoxDecoration

來設定。

BoxDecoration

的參數如下:

屬性 解釋 類型
color 顔色背景 Color
image 圖檔背景 DecorationImage
border 邊界 BoxBorder
borderRadius 圓角邊界半徑 BorderRadiusGeometry
boxShadow 陰影 List<BoxShadow>
gradient 漸變色 Gradient
backgroundBlendMode 背景混合模式 BlendMode
shape 形狀 BoxShape

color

設定背景顔色,

decoration

中的

color

不可與

Container

color

屬性同時設定,設定了

decoration

後,

Container

color

必須去掉。定義方式與

Container

color

定義方式一緻。

body: Center(
  child: Container(
    width: 200,
    height: 200,
    decoration: BoxDecoration(
      color: Colors.blue,
    ),
  ),
),
           
Flutter程式設計之BoxDecoration用法詳解

image

設定圖檔背景,設定

image

需要一個

DecorationImage

類,其中

image

屬性是必須的,其類型是

ImageProvider

,因為

ImageProvider

是抽象類,是以需要用

ImageProvider

的子類來實作。

這裡我們加載一個網絡圖檔來作為圖檔背景,是以就使用

NetworkImage

了,

NetworkImage

ImageProvider

的子類,正好合适。

body: Center(
  child: Container(
    width: 200,
    height: 200,
    decoration: BoxDecoration(
        color: Colors.blue,
        image: DecorationImage(image: NetworkImage("http://wx4.sinaimg.cn/mw690/6a04b428gy1fyrldlsv4yg204r05i3yt.gif"))),
  ),
),
           
Flutter程式設計之BoxDecoration用法詳解

圖檔并沒有充滿整個背景,用

fit

屬性來設定一下吧

body: Center(
  child: Container(
    width: 200,
    height: 200,
    decoration: BoxDecoration(
        color: Colors.blue,
        fit: BoxFit.cover,
        image: DecorationImage(image: NetworkImage("http://wx4.sinaimg.cn/mw690/6a04b428gy1fyrldlsv4yg204r05i3yt.gif"))),
  ),
),
           
Flutter程式設計之BoxDecoration用法詳解

border

設定

Widget

的邊框樣式,設定方式為

Border.xxx

Border

BoxBorder

類型。

  • border.all(Color color, double width,BorderStyle style)

    同時設定上下左右4條邊框的樣式,

    color

    設定顔色,

    width

    設定邊框寬度,

    style

    設定邊框樣式,

    style

    BorderStyle

    枚舉類型,隻有

    none

    solid

    兩個值。

    none

    表示無邊框,

    solid

    表示實線邊框。

    border.all()

    的預設顔色是黑色,邊框寬度為1.0,樣式為

    BorderStyle.solid

Flutter程式設計之BoxDecoration用法詳解

把顔色設定為紅色,寬度設定為5.0來看看效果

body: Center(
  child: Container(
    width: 200,
    height: 200,
    decoration: BoxDecoration(
        color: Colors.blue,
        image: DecorationImage(
            fit: BoxFit.cover,
            image: NetworkImage(
                "http://wx4.sinaimg.cn/mw690/6a04b428gy1fyrldlsv4yg204r05i3yt.gif")),
        border: Border.all(
            color: Colors.red,
            width: 5.0,
        )),
  ),
),
           
Flutter程式設計之BoxDecoration用法詳解

)

  • Border.symmetric(BorderSide vertical, BorderSide horizontal)

    從參數可以看出,是分别設定垂直方向的邊框和水準方向的邊框,即

    vertical

    設定上邊和下邊的邊框,

    horizontal

    設定左邊和右邊的邊框。

    參數是

    BorderSide

    ,而

    BorderSide

    的參數與

    border.all

    的參數一樣,都是

    Color color, double width,BorderStyle style

    ,是以設定方式應該是下面這樣的:
    body: Center(
      child: Container(
        width: 200,
        height: 200,
        decoration: BoxDecoration(
          color: Colors.blue,
          image: DecorationImage(
              fit: BoxFit.cover,
              image: NetworkImage(
                  "http://wx4.sinaimg.cn/mw690/6a04b428gy1fyrldlsv4yg204r05i3yt.gif")),
          border: Border.symmetric(
              vertical: BorderSide( // 垂直方向(上、下)
                color: Colors.red,
                width: 5.0,
              ),
              horizontal: BorderSide( // 水準方向(左、右)
                color: Colors.blue,
                width: 10.0,
              )),
        ),
      ),
    ),
               
    垂直方向上的邊框顔色為紅色,寬度為5.0,水準方向上的邊框顔色為藍色,寬度為10.0。
Flutter程式設計之BoxDecoration用法詳解
  • Border.fromBorderSide(BorderSide side)

    字面上的意思是從

    BorderSide

    中擷取樣式設定,設定方式與

    Border.symmetric

    一緻,因為都是

    BorderSide

    類型,設定效果與

    Border.all

    一緻,因為都是同時設定4條邊框的樣式。

    如:

    body: Center(
      child: Container(
        width: 200,
        height: 200,
        decoration: BoxDecoration(
            color: Colors.blue,
            image: DecorationImage(
                fit: BoxFit.cover,
                image: NetworkImage(
     "http://wx4.sinaimg.cn/mw690/6a04b428gy1fyrldlsv4yg204r05i3yt.gif")),
            border: Border.fromBorderSide(BorderSide(
              color: Colors.red,
              width: 10,
            ))),
      ),
    ),
               
Flutter程式設計之BoxDecoration用法詳解
  • Border({BorderSide top, BorderSide right, BorderSide bottom, BorderSide left})

    四條邊框分别設定,可以設定不同的樣式。
    body: Center(
      child: Container(
        width: 200,
        height: 200,
        decoration: BoxDecoration(
          color: Colors.blue,
          image: DecorationImage(
              fit: BoxFit.cover,
              image: NetworkImage(
                  "http://wx4.sinaimg.cn/mw690/6a04b428gy1fyrldlsv4yg204r05i3yt.gif")),
          border: Border(
              top: BorderSide(color: Colors.blue, width: 3), // 上邊邊框
              right: BorderSide(color: Colors.red, width: 4), // 右側邊框
              bottom: BorderSide(color: Colors.yellow, width: 5), // 底部邊框
              left: BorderSide(color: Colors.cyan, width: 6)), // 左側邊框
        ),
      ),
    ),
               
Flutter程式設計之BoxDecoration用法詳解

borderRadius

設定邊框圓角,類型為

BorderRadiusGeometry

,設定方式為

BorderRadius.xxx

  • BorderRadius.all(Radius radius)

    同時設定4個圓角,參數是

    Radius

    ,設定正圓角,則用

    Radius.circular(double radius)

    。,等同于

    BorderRadius.circular(double radius)

    ;設定橢圓角,則用

    Radius.elliptical(double x, double y)

    body: Center(
      child: Container(
        width: 200,
        height: 200,
        decoration: BoxDecoration(
            color: Colors.blue,
            image: DecorationImage(
                fit: BoxFit.cover,
                image: NetworkImage(
                    "http://wx4.sinaimg.cn/mw690/6a04b428gy1fyrldlsv4yg204r05i3yt.gif")),
            border: Border.all(color: Colors.cyan, width: 5), // 設定邊框
            borderRadius: BorderRadius.all(Radius.circular(10))), // 設定正圓角
      ),
    ),
               
Flutter程式設計之BoxDecoration用法詳解

再試試設定橢圓角是什麼效果

borderRadius: BorderRadius.all(Radius.elliptical(10, 100))), // 設定橢圓角
           
Flutter程式設計之BoxDecoration用法詳解

試驗了很多次,貌似隻有在4條邊框都設定成一緻時,圓角與邊框的效果才能同時出現。

  • BorderRadius.zero

    沒有圓角效果
  • BorderRadius.horizontal({Radius left, Radius right})

    設定水準方向上的圓角,

    left

    設定左上和左下兩個圓角,

    right

    設定右上和右下兩個圓角。
    body: Center(
      child: Container(
        width: 200,
        height: 200,
        decoration: BoxDecoration(
          color: Colors.blue,
          image: DecorationImage(
              fit: BoxFit.cover,
              image: NetworkImage(
                  "http://wx4.sinaimg.cn/mw690/6a04b428gy1fyrldlsv4yg204r05i3yt.gif")),
          border: Border.all(color: Colors.cyan, width: 5),
          borderRadius: BorderRadius.horizontal(
              left: Radius.circular(50), right: Radius.circular(20)), // 設定左上和左下圓角半徑為50,右上和右下圓角半徑為20,也可單獨設定左邊或右邊
        ),
      ),
    ),
               
Flutter程式設計之BoxDecoration用法詳解
  • BorderRadius.vertical({Radius top, Radius bottom})

    設定垂直方向上的圓角,

    top

    設定左上和右上兩個圓角,

    bottom

    設定左下和右下兩個圓角。
    body: Center(
      child: Container(
        width: 200,
        height: 200,
        decoration: BoxDecoration(
          color: Colors.blue,
          image: DecorationImage(
              fit: BoxFit.cover,
              image: NetworkImage(
                  "http://wx4.sinaimg.cn/mw690/6a04b428gy1fyrldlsv4yg204r05i3yt.gif")),
          border: Border.all(color: Colors.cyan, width: 5),
          borderRadius: BorderRadius.vertical(
              top: Radius.circular(50), bottom: Radius.circular(20)), // 設定左上和右上圓角半徑為50,左下和右下圓角半徑為20,也可單獨設定上邊或下邊
        ),
      ),
    ),
               
Flutter程式設計之BoxDecoration用法詳解
  • BorderRadius.only({Radius topLeft, Radius topRight, Radius bottomLeft, Radius bottomRight})

    單獨設定每個角的圓角效果。
    body: Center(
      child: Container(
        width: 200,
        height: 200,
        decoration: BoxDecoration(
          color: Colors.blue,
          image: DecorationImage(
              fit: BoxFit.cover,
              image: NetworkImage(
                  "http://wx4.sinaimg.cn/mw690/6a04b428gy1fyrldlsv4yg204r05i3yt.gif")),
          border: Border.all(color: Colors.cyan, width: 5),
          borderRadius: BorderRadius.only(
              topLeft: Radius.circular(10),
              topRight: Radius.circular(20),
              bottomLeft: Radius.circular(30),
              bottomRight: Radius.circular(40)),
        ),
      ),
    ),
               
Flutter程式設計之BoxDecoration用法詳解

boxShadow

設定陰影效果。參數類型是

List<BoxShadow>

,是一個集合,可以看出應該是多個

BoxShadow

疊加後的效果。

BoxShadow

參數如下:

  • Color color

    :陰影顔色
  • Offset offset

    :偏移量
  • double blurRadius

    :模糊半徑,半徑越大越模糊
  • double spreadRadius

    :延伸範圍半徑,半徑越大,陰影範圍越廣
body: Center(
  child: Container(
    width: 200,
    height: 200,
    decoration: BoxDecoration(
        color: Colors.blue,
        image: DecorationImage(
            fit: BoxFit.cover,
            image: NetworkImage(
                "http://wx4.sinaimg.cn/mw690/6a04b428gy1fyrldlsv4yg204r05i3yt.gif")),
        border: Border.all(color: Colors.cyan, width: 5),
        borderRadius: BorderRadius.only(
            topLeft: Radius.circular(10),
            topRight: Radius.circular(20),
            bottomLeft: Radius.circular(30),
            bottomRight: Radius.circular(40)),
        boxShadow: [
          BoxShadow( // 設定第一個陰影效果
              color: Colors.green, // 陰影顔色為綠色
              offset: Offset(-20, -20),
              blurRadius: 10, // 模糊半徑為10
              spreadRadius: 10), // 延伸半徑為10
        ]),
  ),
),
           
Flutter程式設計之BoxDecoration用法詳解

上圖是沒有設定

Offset

偏移量,我們讓它向左上方各偏移20看看是什麼效果

BoxShadow( // 設定第一個陰影效果
	color: Colors.green, // 陰影顔色為綠色
	offset: Offset(-20, -20), // X軸左移20,Y軸上移20
	blurRadius: 10, // 模糊半徑為10
	spreadRadius: 10), // 延伸半徑為10
           
Flutter程式設計之BoxDecoration用法詳解

再看看設定兩個

BoxShadow

疊加是什麼效果

body: Center(
  child: Container(
    width: 200,
    height: 200,
    decoration: BoxDecoration(
        color: Colors.blue,
        image: DecorationImage(
            fit: BoxFit.cover,
            image: NetworkImage(
                "http://wx4.sinaimg.cn/mw690/6a04b428gy1fyrldlsv4yg204r05i3yt.gif")),
        border: Border.all(color: Colors.cyan, width: 5),
        borderRadius: BorderRadius.only(
            topLeft: Radius.circular(10),
            topRight: Radius.circular(20),
            bottomLeft: Radius.circular(30),
            bottomRight: Radius.circular(40)),
        boxShadow: [
          BoxShadow( // 第一個陰影
              color: Colors.green,
              offset: Offset(-20, -20),
              blurRadius: 10,
              spreadRadius: 10),
          BoxShadow( // 增加第二個陰影
              color: Colors.yellow, // 陰影顔色為黃色
              offset: Offset(10, 10), // 右下方偏移10
              blurRadius: 20,
              spreadRadius: 20),
        ]),
  ),
),
           
Flutter程式設計之BoxDecoration用法詳解

可以看出,多個

BoxShadow

确實是疊加的效果,并且後面的

BoxShadow

會在之前的

BoxShadow

的上方。

對比一下兩個

BoxShadow

交換位置的效果

黃色陰影在上 綠色陰影在上
Flutter程式設計之BoxDecoration用法詳解
Flutter程式設計之BoxDecoration用法詳解

gradient

設定漸變背景色,類型是

Gradient

Gradient

是抽象類,它有3個實作類:

  • LinearGradient

    :線性漸變

    LinearGradient(AlignmentGeometry begin, AlignmentGeometry end, List<Color> colors, List<double> stops, TileMode tileMode, GradientTransform transform)

    • colors

      漸變色數組,不可為空,如

      [Colors.red, Colors.yellow, Colors.green]

      body: Center(
        child: Container(
          width: 200,
          height: 200,
          decoration: BoxDecoration(
            gradient: LinearGradient(
              colors: [Colors.red, Colors.yellow, Colors.green],
            ),
          ),
        ),
      ),
                 
    • stops

Flutter程式設計之BoxDecoration用法詳解

漸變色的終止百分比位置的數組,可為空。如

[0.1, 0.3, 0.5]

,當

stops

不為空時,其長度必須和

colors

一緻。

body: Center(
      child: Container(
        width: 200,
        height: 200,
        decoration: BoxDecoration(
          gradient: LinearGradient(
            colors: [Colors.red, Colors.yellow, Colors.green],
            stops: [0.1, 0.3, 0.5],
          ),
        ),
      ),
    ),
           
Flutter程式設計之BoxDecoration用法詳解

從圖中可以不太容易看出來

stops

是什麼意思。其實

stops

中的每個元素的取值範圍是

0.0 ~ 1.0

,把

Widget

begin

開始位置到

end

結束位置平均分為10份,每個元素之間表示一個範圍值,是以一般

stops

裡的元素都是遞增的,如果設定成

[0.1, 0.3, 0.1]

這種遞增再遞減就沒有實際的意義了。

對于上面例子來說,因為沒指定

begin

end

的值(這兩個值的含義下面會講到),那麼就是預設值

Alignment.centerLeft

Alignment.centerRight

,表示從左側中間往右側中間水準漸變。

[Colors.red, Colors.yellow, Colors.green]

[0.1, 0.3, 0.5]

這兩個數組表示:

0.0 ~ 0.1:紅色
0.1 ~ 0.3:紅色到黃色漸變
0.3 ~ 0.5:黃色到綠色漸變
0.5 ~ 1.0:綠色
           
Flutter程式設計之BoxDecoration用法詳解
  • begin

    end

    漸變顔色的起止位置,表示漸變色從

    begin

    位置開始,到

    end

    位置結束。她們都是

    AlignmentGeometry

    類型,表示對齊方式。和

    Container

    的對齊方式

    alignment

    一樣,将一個

    Widget

    分為了9個點(參考Container的對齊方式):
Flutter程式設計之BoxDecoration用法詳解

預設的對齊方式是從左側中間到右側中間漸變,即從

(-1, 0)

(0 1)

如果将上例中的

begin

指定為

Alignment.bottomLeft

end

指定為

Alignment.topRight

,則漸變方向變成了從

左下角

右上角

漸變。

Flutter程式設計之BoxDecoration用法詳解
Flutter程式設計之BoxDecoration用法詳解
  • tileMode

    平鋪模式,共有三種模式,

    TileMode.clamp

    TileMode.repeated

    TileMode.mirror

    ,預設模式是

    TileMode.clamp

    如果在上例的基礎上直接設定

    tileMode

    是看不到任何效果的,因為預設情況下始末位置就是占滿整個

    Widget

    我們現在把漸變區域設定為整個區域的1/4,水準向右漸變。

    body: Center(
      child: Container(
        width: 200,
        height: 200,
        decoration: BoxDecoration(
          gradient: LinearGradient(
              begin: Alignment(-1, 0),
              end: Alignment(-0.5, 0),
              colors: [Colors.red, Colors.yellow, Colors.green],
              stops: [0.1, 0.5, 0.7],
              tileMode: TileMode.xxx),
        ),
      ),
    ),
               

    begin

    (-1, 0)

    end

    (-0.5, 0)

    ,剛好占據1/4,。
Flutter程式設計之BoxDecoration用法詳解
TileMode.clamp TileMode.repeated TileMode.mirror
Flutter程式設計之BoxDecoration用法詳解
Flutter程式設計之BoxDecoration用法詳解
Flutter程式設計之BoxDecoration用法詳解
  • RadialGradient

    :放射漸變

    RadialGradient({AlignmentGeometry center, double radius, List<Color> colors, List<double> stops, TileMode tileMode, AlignmentGeometry focal, double focalRadius})

    其中

    colors

    stops

    和線性漸變一樣,接下來說說剩下的幾個參數:
    • center

      掃描區域的中心位置,也就是圓心的位置,預設是

      Alignment.center

      ,即

      Widget

      中心的位置。
      body: Center(
        child: Container(
          width: 200,
          height: 200,
          decoration: BoxDecoration(
            gradient: RadialGradient(
              colors: [Colors.red, Colors.yellow, Colors.green],
              stops: [0.1, 0.5, 0.7],
            ),
          ),
        ),
      ),
                 
Flutter程式設計之BoxDecoration用法詳解

center

的位置設定到右上角

Flutter程式設計之BoxDecoration用法詳解
  • radius

    掃描漸變區域半徑比例,預設為

    0.5

    ,即矩形

    Widget

    較短邊的一半。
Flutter程式設計之BoxDecoration用法詳解

radius

設定成1,

Flutter程式設計之BoxDecoration用法詳解
  • tileMode
  • focal

    focalRadius

    還沒了解清楚這是什麼
  • SweepGradient

    :掃描漸變

    SweepGradient({AlignmentGeometry center, double startAngle, double endAngle, List<Color> colors, List<double> stops, TileMode tileMode, GradientTransform transform})

    除了

    startAngle

    endAngle

    之外,其他的參數都和上面的一樣。
    • startAngle

      開始漸變的弧度,覺得這個地方的命名并不合适,應該叫

      startRadians

      才對,意思是開始弧度,

      為一周360度,預設值是0,為右側中間的位置。
    • endAngle

      結束漸變的弧度,預設值是

      ,還有一點就是

      endAngle

      必須大于

      startAngle

      ,否則不繪制。
import 'dart:math'; // 需要引入math包

body: Center(
  child: Container(
    width: 200,
    height: 200,
    decoration: BoxDecoration(
      gradient: SweepGradient(
          colors: [Colors.red, Colors.blue, Colors.yellow],
          startAngle: pi,
          endAngle: pi * 2),
    ),
  ),
),
           
Flutter程式設計之BoxDecoration用法詳解

漸變範圍從弧度為

π

,是以真正的掃描漸變範圍在上面一半,下面一半紅色顯示的是開始顔色紅色。

現在我們把掃描範圍設定成從

3 * π/ 4

,再看看效果

Flutter程式設計之BoxDecoration用法詳解

從上面2個效果圖中可以看出來,在預設混合模式

TileMode.clamp

中,當掃描範圍不滿一周時,接近0弧度的區域填充的是

colors

中設定的起始顔色,越接近

弧度的區域填充的是

colors

中設定的結束顔色。

最後來對比一下最後一個例子中在不同混合模式下的效果

body: Center(
  child: Container(
    width: 200,
    height: 200,
    decoration: BoxDecoration(
      gradient: SweepGradient(
        colors: [Colors.red, Colors.blue, Colors.yellow],
        startAngle: 0,
        endAngle: 3 * pi / 4,
        tileMode: xxx,
      ),
    ),
  ),
),
           
TileMode.clamp TileMode.repeated TileMode.mirror
Flutter程式設計之BoxDecoration用法詳解
Flutter程式設計之BoxDecoration用法詳解
Flutter程式設計之BoxDecoration用法詳解