Flutter之BoxDecoration用法詳解

前言

相關文章:Flutter學習目錄git

github地址:Flutter學習github

文章結構算法

  • Gradient Property
  • TileMode property
  • RadialGradient
  • Image Property
  • centerSlice Property
  • ColorFilter Property
  • fit Property
  • repeat Property
  • matchTextDirection Property
  • Border Property
  • borderRadius Property
  • boxShadow Property
  • shape Property
  • Padding Property

介紹:

BoxDecoration類提供了多種繪製盒子的方法。數組

這個盒子有邊框、主體、陰影組成。bash

盒子的形狀多是圓形或者長方形。若是是長方形,borderRadius屬性能夠控制邊界的圓角大小。網絡

盒子的主體部分在layers層繪製。盒子的最底層是color層,在color層上面是gradient層color層gradient層都是填充整個盒子。最後是image層,它的對齊方式右DecorationImage類控制。less

邊框在主體上層繪製,陰影在主體下層繪製。ide


這裏咱們在一個空的container中,使用boxDecoration的color屬性 代碼以下:post

//Colors
class BoxDecoration_Colors_Widget extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        decoration: BoxDecoration(
          color: Colors.purple
        ),
        child: FlutterLogo(
          size: 200.0,
        ),
      ),
    );
  }
}
複製代碼

效果圖以下: 學習

圖1 Colors使用

注意: 若是你使用了decoration屬性,就不能再使用color屬性。這個color參數只是「decoration: new BoxDecoration(color:color)」的簡寫。所以,如下代碼運行會提示錯誤:

child: Container(
        //兩者不能同時出現
        decoration: BoxDecoration(
          color: Colors.purple
        ),
        color: Colors.green,
      ),
複製代碼

1、Gradient Property

在填充整個盒子模型時,會使用到漸變屬性。

若是使用了漸變屬性,color屬性將不會有效果。

這個漸變在image圖層下面繪製。

漸變屬性的值能夠是LinearGradient類或者RadialGradient類。

這裏將詳細介紹LinearGradient和RadialGradient。

LinearGradient有5個重要屬性:

  • begin(漸變開始的位置)
  • end(漸變結束的位置)
  • colors(漸變顏色,是數組)
  • stops(值列表,裝有0.0到1.0的數值)
  • tileMode(漸變平鋪模式,指定在開始和結束之外的區域平鋪模式)

代碼以下:

//Gradient Property
class Gradient_Property_Widget extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        decoration: BoxDecoration(
          color: Colors.purple,
          gradient: LinearGradient(
              colors: [Colors.red, Colors.cyan],
          )
        ),
        child: FlutterLogo(
          size: 200.0,
        ),
      ),
    );
  }
} 
複製代碼

效果圖以下:

圖2 Gradient屬性

若是咱們沒有添加begin和start屬性,這個漸變將會使用默認屬性,從左向右繪製。


這裏咱們嘗試添加begin和end屬性,你將使用Alignment類的兩個屬性。 代碼以下:

//Gradient Property
//begin和end屬性
class Gradient_Property_beginAndEnd_Widget extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        decoration: BoxDecoration(
            color: Colors.purple,
            gradient: LinearGradient(
              colors: [Colors.red, Colors.cyan],
              begin: Alignment.centerRight,
              end: Alignment.centerLeft
            ),
        ),
        child: FlutterLogo(
          size: 200.0,
        ),
      ),
    );
  }
}
複製代碼

效果圖以下:

圖3 Gradient屬性

記住它是一個線性漸變。所以若是begin是bottomRight,end是bottomLeft,那麼這個漸變將從右向左繪製。如下設置效果同樣:

begin: Alignment.centerRight & end: Alignment.centerLeft

begin: Alignment.topRight & end: Alignment.topLeft


一樣你可使用Alignment類中的座標系屬性X和Y。 更多關於Alignment類詳情查看Flutter之Container用法詳解。 代碼以下;

//Gradient Property
//begin和end屬性
class Gradient_Property_beginAndEnd_Widget extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        decoration: BoxDecoration(
            color: Colors.purple,
            gradient: LinearGradient(
              colors: [Colors.red, Colors.cyan],
              begin: Alignment.centerRight,
              //end: Alignment.centerLeft
              end: Alignment(-1.0, -1.0)//效果同上
            ),
        ),
        child: FlutterLogo(
          size: 200.0,
        ),
      ),
    );
  }
}
複製代碼

效果圖以下:

圖4 Gradient屬性


2、TileMode property

在開始和結束以前,此漸變應如何平鋪該區域之外的平面。

TileMode值:

  • TileMode.clamp
  • TileMode.mirror
  • TileMode.repeated

圖5 TileMode數值

TileMode.clamp 是默認的渲染方式

代碼以下:

//TileMode property
//TileMode.clamp
class TileMode_Clamp_Property_Widget extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        decoration: BoxDecoration(
          color: Colors.purple,
          gradient: LinearGradient(
              colors: [Colors.red, Colors.cyan],
              begin: Alignment.centerRight,
              end: Alignment(0.8,0.0),
              tileMode: TileMode.clamp
          )
        ),
        child: FlutterLogo(
          size: 200.0,
        ),
      ),
    );
  }
}
複製代碼

效果圖以下:

圖6 TileMode.clamp屬性


TileMode.mirror

代碼以下:

//TileMode property
//TileMode.mirror
class TileMode_Mirror_Property_Widget extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        decoration: BoxDecoration(
          color: Colors.purple,
          gradient: LinearGradient(
              colors: [Colors.red, Colors.cyan],
              begin:Alignment.centerRight,
              end: Alignment(0.8,0.0),
              tileMode: TileMode.mirror
          ),
        ),
        child: FlutterLogo(
          size: 200.0,
        ),
      ),
    );
  }
}
複製代碼

效果圖以下:

圖7 TileMode.mirror


TileMode.repeated

代碼以下:

//TileMode property
//TileMode.repeated
class TileMode_Repeated_Property_Widget extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        decoration: BoxDecoration(
          color: Colors.purple,
          gradient: LinearGradient(
              colors: [Colors.red, Colors.cyan],
              begin: Alignment.centerRight,
              end: Alignment(0.8,0.0),
              tileMode: TileMode.repeated
          )
        ),
        child: FlutterLogo(
          size: 200.0,
        ),
      ),
    );
  }
}
複製代碼

效果圖以下:

圖8 TileMode.repeated


Stops

一個從0.0到1.0的值列表,數值表示梯度方向上的分割比例。

若是Stops不爲空,那麼它必須與colors中顏色個數保持一致,不然運行異常。

若是第一個數值不爲0,此時會默認一個stop位置0.0,顏色和colors中第一個顏色相同。

若是最後一個數值不爲1.0,此時會默認一個stop位置1.0,顏色和colors中最後一個顏色相同。

stops值列表中的數據必須是升序。若是stops值列表有一個數據小於前一個數據值,那麼這個數據會被默認等於前面的數據值。

若是stops是空的,那麼stops裏面默認存放一組均勻分佈的點,而且第一個點是0.0,最後一個點是1.0。

代碼以下:

//Gradient Property
//Stops屬性
class Stops_Property_Widget extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        decoration: BoxDecoration(
          color: Colors.purple,
          gradient: LinearGradient(
              colors: [Colors.red,Colors.cyan,Colors.purple,Colors.lightGreenAccent],
              begin:Alignment.centerRight,
              end: Alignment.centerLeft,
              tileMode: TileMode.clamp,
              stops: [0.3,0.5,0.6,0.7]//要與上面數組顏色個數一致,不然顯示不出來
          ),
        ),
        child: FlutterLogo(
          size: 200.0,
        ),
      ),
    );
  }
}
複製代碼

效果圖以下:

圖9 stops屬性


3、RadialGradient

徑向漸變有5個重要屬性

  • center(漸變的中心)
  • radius(漸變的半徑,浮點型,具體數值須要乘以盒子的寬度)
  • colors(漸變顏色,是數組)
  • stops(值列表,裝有0.0到1.0的數值)
  • tileMode(漸變平鋪模式,指定在圓環之外的區域平鋪模式)

代碼以下:

//RadialGradient
class RadialGradient_Widget extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        decoration: BoxDecoration(
          color: Colors.purple,
          gradient: RadialGradient(
              colors: [Colors.red, Colors.cyan, Colors.purple, Colors.lightGreenAccent],
              center: Alignment(-0.7, -0.6),
              radius: 0.2,
              tileMode: TileMode.clamp,
              stops: [0.3, 0.5, 0.6, 0.7]
          )
        ),
        child: FlutterLogo(
          size: 200.0,
        ),
      ),
    );
  }
}
複製代碼

效果圖以下:

圖10 RadialGradient

同線性漸變同樣,Center屬性用Alignment類取值,取值範圍是0.0到1.0。

若是在寬度是200.0的盒子上繪製徑向漸變,那麼radius是0.5,就表明100.0。

圖10


4、Image Property

在color層和gradient層上方繪製圖像。image屬性的值是DecorationImage類。

DecorationImage類包含如下屬性:

image

這個圖片被繪製到圖層中。一般,這個圖片將是AssetImage(應用程序內部提供的圖片)或者NetworkImage(用於從網絡獲取的圖片)。 代碼以下:

//Image Property
class Image_Property_Widget extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        decoration: BoxDecoration(
          color: Colors.purple,
          gradient: RadialGradient(
              colors: [Colors.red, Colors.cyan, Colors.purple, Colors.lightGreenAccent],
              center: Alignment(0.0, 0.0),
              radius: 0.5,
              tileMode: TileMode.clamp,
              stops: [0.3, 0.5, 0.9, 1.0]
          ),
          image: DecorationImage(
            image: NetworkImage("http://jlouage.com/images/author.jpg"),
        ),
      ),
      child: FlutterLogo(
        size: 200.0,
      ),
     ),
    );
  }
}
複製代碼

效果圖以下:

圖11 Image

從上面圖片能夠看出,這個圖片是繪製在color層和gradient層上方。


5、centerSlice Property

centerSlice與Android Studio中的9補丁png相同。這是一種用於縮放圖像的技術,使得4個角保持不縮放,可是四個邊在一個軸上縮放,中間在兩個軸上縮放。

圖12 centerSlice Property

這個centerSlice類的數值是Rect類。咱們須要從左邊和頂邊,寬度和高度構造一個矩形。 讓咱們開始瞭解咱們圖片的大小。

圖13

Width = 320 & the Height = 190

咱們須要使用Rect.fromLTWH(double left, double top, double width, double height)類來獲取數據。

咱們的centerSlice是圖片中間的綠色矩形。要建立它,咱們須要知道橙色矩形的寬度,把它放在左邊的值和紫色矩形的高度,並把它做爲最高值。

圖14

Rect.fromLTWH(50.0, 50.0, double width, double height)

因此咱們告訴Rect類從左邊移動50,從圖片頂部移動50,而後從上面標記的黃點開始繪製矩形。

圖15

在上圖中,矩形的寬度爲220,高度爲90,所以最終的類值應爲Rect.fromLTWH(50.0, 50.0, 220.0, 90.0)

代碼以下:

//centerSlice Property
//關聯問題:
//https://github.com/flutter/flutter/issues/16098
class centerSlice_Property_Widget extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        decoration: BoxDecoration(
          image: DecorationImage(
              image: AssetImage("images/9_patch_scaled_320x190.jpeg"),
              centerSlice: new Rect.fromLTWH(50.0, 50.0, 220.0, 90.0),
              fit: BoxFit.fill,
          )
        ),
        child: Container(
          //color: Colors.yellow,
          width: 110.0,
          height: 110.0,
        ),
      ),
    );
  }
}
複製代碼

效果圖以下:

圖16

咱們能夠看出4個紅色的區域沒有縮放。如今增長container的子控件的寬和高。

代碼以下:

//centerSlice Property
//關聯問題:
//https://github.com/flutter/flutter/issues/16098
class centerSlice_Property_Widget extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        decoration: BoxDecoration(
          image: DecorationImage(
              image: AssetImage("images/9_patch_scaled_320x190.jpeg"),
              centerSlice: new Rect.fromLTWH(50.0, 50.0, 220.0, 90.0),
              fit: BoxFit.fill,
          )
        ),
        child: Container(
          //color: Colors.yellow,

          //width: 110.0,
          //height: 110.0,
          width: 350.0,
          height: 450.0,
        ),
      ),
    );
  }
}
複製代碼

效果圖以下:

圖17


6、ColorFilter Property

在繪製圖像以前應用於圖像的濾色器。這個屬性值是 ColorFilter類,方法是ColorFilter.mode。

ColorFilter.mode()有兩個參數,第一個是濾色鏡,第二個是blend mode(混合模式)。

咱們將會使用下面的圖片,而且在上面應用不一樣的ColorFilter。

圖18

BlendMode.src

咱們將用Colors.red.withOpacity(0.5)和多種混合模式。下面咱們將使用BlendMode.src。這將刪除目標圖像,僅繪製源圖像。這裏目標圖像是image,源圖像是Container(最裏層的)。 代碼以下:

//ColorFilter Property
class ColorFilter_Property_Widget extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        width: double.infinity,
        height: double.infinity,
        //color: Colors.white,
        color: Colors.grey,
        child: Container(
          decoration: BoxDecoration(
            image: DecorationImage(
                image:AssetImage("images/JL-Logo-empty.png"),
                colorFilter: ColorFilter.mode(Colors.red.withOpacity(0.5), BlendMode.src)
            ),
          ),
        ),
      ),
    );
  }
}
複製代碼

效果圖以下:

圖19 BlendMode.src

BlendMode.clear

如今將要使用BlendMode.clear。這將丟棄源圖像和目標圖像,不會留下任何內容。

效果圖以下:

圖20 BlendMode.clear


BlendMode.color

獲取源圖像的​​色調和飽和度以及目標圖像的亮度。 效果是使用源圖像爲目標圖像着色。 輸出圖像的不透明度的計算方法與srcOver相同。 在源圖像中徹底透明的區域從目的地獲取其色調和飽和度。 簡單來講,就是用當前Container顏色給image染色(通俗易懂)。 效果圖以下:

圖21 BlendMode.color


BlendMode.colorBurn

將目標的倒數除以源,並反轉結果。 反轉組件意味着徹底飽和的通道(不透明的白色)被視爲值0.0,一般被視爲0.0(黑色,透明)的值被視爲1.0。 這個說法有點太專業,本身都有點迷糊了!!!直接看效果吧。 效果圖以下:

圖22 BlendMode.colorBurn


BlendMode.colorDodge

將目標除以源的倒數。 反轉組件意味着徹底飽和的通道(不透明的白色)被視爲值0.0,一般被視爲0.0(黑色,透明)的值被視爲1.0。 一樣感受一頭霧水,看效果圖吧!!! 效果圖以下:

圖23 BlendMode.colorDodge


BlendMode.darken

經過從每一個顏色通道中選擇最低值來合成源圖像和目標圖像。 輸出圖像的不透明度的計算方法與srcOver相同。 效果圖以下:

圖24 BlendMode.darken


BlendMode.difference

從每一個通道的較大值中減去較小的值。 合成黑色沒有效果;合成白色會反轉另外一幅圖像的顏色。 輸出圖像的不透明度的計算方法與srcOver相同。 效果圖以下:

圖25 BlendMode.difference


BlendMode.dst

刪除源圖像,僅繪製目標圖像。 從概念上講,源圖像被丟棄,保持目的地不變。 這對應於「目標」Porter-Duff運算符。 效果圖以下:

圖26 BlendMode.dst


BlendMode.dstATop

將目標圖像合成到源圖像上,但僅限於它與源重疊的位置。 這對應於「Destination atop Source」Porter-Duff運算符。 這本質上是dstOver運算符,但輸出的不透明度通道設置爲源圖像的不透明度通道,而不是圖像的不透明度通道的組合。 對於源位於頂部而非目標的變體,請參閱srcATop。 效果圖以下:

圖27 BlendMode.dstATop


BlendMode.dstIn

顯示目標圖像,但僅顯示兩個圖像重疊的位置。 源圖像未呈現,僅被視爲蒙版。忽略源的顏色通道,只有不透明度纔有效。 要顯示源圖像,請考慮srcIn。 要反轉掩碼的語義(僅顯示目標所在的源,而不是缺乏目標的位置),請考慮dstOut。 這對應於「源中的目的地」Porter-Duff運算符。 效果圖以下:

圖28 BlendMode.dstIn


BlendMode.dstOut

顯示目標圖像,但僅顯示兩個圖像不重疊的位置。源圖像未呈現,僅被視爲蒙版。忽略源的顏色通道,只有不透明度纔有效。 要顯示源圖像,請考慮srcOut。 要反轉掩碼的語義(僅顯示源存在的目標,而不是缺乏的位置),請考慮dstIn。 這對應於「Destination out Source」Porter-Duff運算符。 效果圖以下:

圖29 BlendMode.dstOut


BlendMode.dstOver

合成目標圖像下的源圖像。 這與srcOver相反。 這對應於「源上的目標」Porter-Duff運算符。 效果圖以下:

圖30 BlendMode.dstOver


BlendMode.exclusion

從兩個圖像的總和中減去兩個圖像的乘積的兩倍。 合成黑色沒有效果;合成白色會反轉另外一幅圖像的顏色。 輸出圖像的不透明度的計算方法與srcOver相同。 效果圖以下:

圖31 BlendMode.exclusion

BlendMode.hardLight

將源圖像和目標圖像的組件調整爲有利於源後,將它們相乘。 具體來講,若是源值較小,則將其與目標值相乘,而目標值較小,它將目標值的倒數乘以源值的倒數,而後反轉結果。 反轉組件意味着徹底飽和的通道(不透明的白色)被視爲值0.0,一般被視爲0.0(黑色,透明)的值被視爲1.0。 效果圖以下:

圖32 BlendMode.hardLight


BlendMode.hue

獲取源圖像的​​色調,以及目標圖像的飽和度和亮度。 效果是使用源圖像爲目標圖像着色。 輸出圖像的不透明度的計算方法與srcOver相同。 在源圖像中徹底透明的區域從目的地獲取其色調。 效果圖以下:

圖33 BlendMode.hue


BlendMode.lighten

經過從每一個顏色通道中選擇最高值來合成源圖像和目標圖像。 輸出圖像的不透明度的計算方法與srcOver相同。 效果圖以下:

圖34 BlendMode.lighten


BlendMode.luminosity

獲取源圖像的​​亮度,以及目標圖像的色調和飽和度。 輸出圖像的不透明度的計算方法與srcOver相同。 在源圖像中徹底透明的區域從目的地獲取其亮度。 效果圖以下:

圖35 BlendMode.luminosity


BlendMode.modulate

將源圖像和目標圖像的顏色份量相乘。 這隻能產生相同或較暗的顏色(乘以白色,1.0,結果不變;乘以黑色,0.0,結果爲黑色)。 合成兩個不透明圖像時,這與在投影儀上重疊兩個透明膠片具備類似的效果。 對於也乘以alpha通道的變體,請考慮乘法。 效果圖以下:

圖36 BlendMode.modulate


BlendMode.multiply

將源圖像和目標圖像的組件相乘,包括Alpha通道。 這隻能產生相同或較暗的顏色(乘以白色,1.0,結果不變;乘以黑色,0.0,結果爲黑色)。 因爲Alpha通道也是相乘的,所以一個圖像中的徹底透明像素(不透明度爲0.0)會在輸出中產生徹底透明的像素。這與dstIn相似,但顏色組合在一塊兒。 對於將顏色相乘但不會乘以alpha通道的變體,請考慮調製。 效果圖以下:

圖37 BlendMode.multiply


BlendMode.overlay

在調整源圖像和目標圖像的組件以使其有利於目標以後,將其相乘。 具體來講,若是目標值較小,則將其與源值相乘,而源值較小,它將源值的倒數乘以目標值的倒數,而後反轉結果。 反轉組件意味着徹底飽和的通道(不透明的白色)被視爲值0.0,一般被視爲0.0(黑色,透明)的值被視爲1.0。 效果圖以下:

圖38 BlendMode.overlay


BlendMode.plus

對源圖像和目標圖像的組件求和。 其中一個圖像的像素中的透明度下降了該圖像對相應輸出像素的貢獻,就好像該圖像中該像素的顏色較暗同樣。 這對應於「Source plus Destination」Porter-Duff運算符。 效果圖以下:

圖39 BlendMode.plus


BlendMode.saturation

獲取源圖像的​​飽和度以及目標圖像的色調和亮度。 輸出圖像的不透明度的計算方法與srcOver相同。 在源圖像中徹底透明的區域從目的地獲取飽和度。 效果圖以下:

圖40 BlendMode.saturation


BlendMode.screen

將源圖像和目標圖像的份量的倒數相乘,並反轉結果。 反轉組件意味着徹底飽和的通道(不透明的白色)被視爲值0.0,一般被視爲0.0(黑色,透明)的值被視爲1.0。 這與調製混合模式基本相同,可是在乘法以前將顏色的值反轉,而且在渲染以前將結果反轉回來。 這隻能產生相同或較淺的顏色(乘以黑色,1.0,結果不變;乘以白色,0.0,結果爲白色)。一樣,在alpha通道中,它只能產生更多不透明的顏色。 這與兩臺同時在同一屏幕上顯示圖像的投影機具備類似的效果。 效果圖以下:

圖41 BlendMode.screen


BlendMode.softLight

對於低於0.5的源值,使用colorDodge,對於高於0.5的源值,使用colorBurn。 這致使與覆蓋類似但更柔和的效果。 效果圖以下:

圖42 BlendMode.softLight


BlendMode.srcATop

將源圖像合成到目標圖像上,但僅限於它與目標重疊的位置。 這對應於「Source atop Destination」Porter-Duff運算符。 這其實是srcOver運算符,但輸出的不透明度通道設置爲目標圖像的不透明度通道,而不是兩個圖像的不透明度通道的組合。 對於目標位於頂部而非源的變體,請參閱dstATop。 效果圖以下:

圖43 BlendMode.srcATop


BlendMode.srcIn

顯示源圖像,但僅顯示兩個圖像重疊的位置。目標圖像不會渲染,僅將其視爲蒙版。將忽略目標的顏色通道,只有不透明度纔有效。 要顯示目標圖像,請考慮dstIn。 要反轉掩碼的語義(僅顯示目標不存在的源,而不是存在的位置),請考慮srcOut。 這對應於「目的地來源」Porter-Duff運算符。 效果圖以下:

圖44 BlendMode.srcIn


BlendMode.srcOut

顯示源圖像,但僅顯示兩個圖像不重疊的位置。目標圖像不會渲染,僅將其視爲蒙版。將忽略目標的顏色通道,只有不透明度纔有效。 要顯示目標圖像,請考慮dstOut。 要反轉掩碼的語義(僅顯示目標所在的源,而不是缺乏的位置),請考慮srcIn。 這對應於「Source out Destination」Porter-Duff運算符。 效果圖以下:

圖45 BlendMode.srcOut


BlendMode.srcOver

將源圖像合成到目標圖像上。 這是默認值。它表明了最直觀的狀況,其中形狀被繪製在下面的內部,透明區域顯示目標層。 這對應於「Source over Destination」Porter-Duff運算符,也稱爲Painter算法。 效果圖以下:

圖46 BlendMode.srcOver


BlendMode.xor

將按位xor運算符應用於源圖像和目標圖像。這會留下重疊的透明度。 這對應於「Source xor Destination」Porter-Duff運算符。 效果圖以下:

圖47 BlendMode.xor


7、fit Property

如何將圖片放在盒子裏。fit屬性的值是枚舉類型的BoxFit。

  • contain
  • cover
  • fill
  • fitHeight
  • fitWidth
  • none
  • scaleDown

代碼以下:

//fit Property
class fit_Property_Widget extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        width: double.infinity,
        height: double.infinity,
        color: Colors.white,
        child: Container(
          decoration: BoxDecoration(
            image: DecorationImage(
                image: NetworkImage("http://jlouage.com/images/author.jpg"),
                fit: BoxFit.contain
            )
          ),
        ),
      ),
    );
  }
}
複製代碼

contain

在子類寬高比不變的前提下,子類儘量的大,充滿父類。通常狀況下,寬度或者高度達到最大值時,就會中止縮放。

圖48 contain

cover

圖像應該儘量小,但覆蓋整個渲染框。因此小圖片會被放大拉伸,直至覆蓋整個渲染框。若是圖片大於渲染框,圖片會顯示部分。

圖49 cover

fill

圖片會去適應當前渲染框,調整自身大小,充滿整個屏幕。

圖50 fill

fitHeight

高度要充滿屏幕,不管寬度方向上,圖片是否會溢出。

圖51 fitHeight

fitWidth

寬度要充滿屏幕,不管高度方向上,圖片是否會溢出。

圖52 fitWidth

none

圖片按照原圖展現,不進行任何縮放,超出父類的部分會被裁剪掉。保證圖片居中顯示。

圖53 none

scaleDown

調整圖片,讓圖片居中顯示。若是須要縮小圖片(同比例縮放),則與contain相同,不然與none相同。

圖54 scaleDown

8、repeat Property

  • noRepeat
  • repeat
  • repeatX
  • repeatY

noRepeat

讓Container未覆蓋部分保持透明,只會出現一張圖片。

代碼以下:

//repeat Property
class repeat_Property_Widget extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        width: double.infinity,
        height: double.infinity,
        color: Colors.white,
        child: Container(
          decoration: BoxDecoration(
            image: DecorationImage(
                image: AssetImage("images/JL-Logo-150.png"),
                repeat: ImageRepeat.noRepeat,
                //repeat: ImageRepeat.repeat,
                //repeat: ImageRepeat.repeatX,
                //repeat: ImageRepeat.repeatY
            )
          ),
        ),
      ),
    );
  }
}
複製代碼

效果圖以下:

圖55 noRepeat


repeat

在x和y方向上重複圖像,直到填充滿容器。

代碼以下:

//repeat Property
class repeat_Property_Widget extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        width: double.infinity,
        height: double.infinity,
        color: Colors.white,
        child: Container(
          decoration: BoxDecoration(
            image: DecorationImage(
                image: AssetImage("images/JL-Logo-150.png"),
                //repeat: ImageRepeat.noRepeat,
                repeat: ImageRepeat.repeat,
                //repeat: ImageRepeat.repeatX,
                //repeat: ImageRepeat.repeatY
            )
          ),
        ),
      ),
    );
  }
}
複製代碼

效果圖以下:

圖56 repeat


repeatX

沿x方向重複圖像,直到水平填充滿容器。

代碼以下:

//repeat Property
class repeat_Property_Widget extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        width: double.infinity,
        height: double.infinity,
        color: Colors.white,
        child: Container(
          decoration: BoxDecoration(
            image: DecorationImage(
                image: AssetImage("images/JL-Logo-150.png"),
                //repeat: ImageRepeat.noRepeat,
                //repeat: ImageRepeat.repeat,
                repeat: ImageRepeat.repeatX,
                //repeat: ImageRepeat.repeatY
            )
          ),
        ),
      ),
    );
  }
}
複製代碼

效果圖以下:

圖56 repeatX


repeatY

沿y方向重複圖像,直到垂直填充滿容器。

代碼以下:

//repeat Property
class repeat_Property_Widget extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        width: double.infinity,
        height: double.infinity,
        color: Colors.white,
        child: Container(
          decoration: BoxDecoration(
            image: DecorationImage(
                image: AssetImage("images/JL-Logo-150.png"),
                //repeat: ImageRepeat.noRepeat,
                //repeat: ImageRepeat.repeat,
                //repeat: ImageRepeat.repeatX,
                repeat: ImageRepeat.repeatY
            )
          ),
        ),
      ),
    );
  }
}
複製代碼

效果圖以下:

圖57 repeatY


9、matchTextDirection Property

決定圖片是否根據TextDirection設置進行變換。它的值是truefalse

這個屬性須要配合Directionality使用。

若是當前是TextDirection.ltr,matchTextDirection設置位true,那麼圖片將從原點的左上方開始繪製(圖片正常繪製的方向)。 若是當前是TextDirection.rtl,matchTextDirection設置位true,那麼圖片將從原點的右上方開始繪製,圖片進行反轉。 代碼以下:

//matchTextDirection Property
//配合Directionality
class matchTextDirection_Property_Widget extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        width: double.infinity,
        height: double.infinity,
        color: Colors.white,
        child: Directionality(
            textDirection: TextDirection.rtl,
            child: Container(
              decoration: BoxDecoration(
                image: DecorationImage(
                    image: AssetImage("images/icon1.png"),
                  matchTextDirection: true,
                )
              ),
            )
        ),
      ),
    );
  }
}
複製代碼

效果圖以下:

圖58 matchTextDirection


10、Border Property

在背景color、gradient或image上面繪製邊框。

Border Property 能夠取值爲 Border Class、Border.all、BorderDirectional Class。

其中Border和BorderDirectional能夠用於設置特定邊界邊框。 Border.all用於設置全部邊框。

這裏先介紹Border.all屬性,它有3個參數:

  • color:設置顏色
  • width:邊框寬度
  • style:邊界風格,這裏主要有2個風格:BorderStyle.solid 和BorderStyle.none。 代碼以下:
//Border Property
class Border_Property_Widget extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        width: 300.0,
        height: 300.0,
        color: Colors.white,
        child: Container(
          decoration: BoxDecoration(
            border: Border.all(
              color: Colors.green,
              width: 5.0,
              style: BorderStyle.solid
            ),
            image: DecorationImage(
               image:AssetImage("images/JL-Logo-150.png")
             )    
          ),
        ),
      ),
    );
  }
}
複製代碼

效果圖以下:

圖59 Border Property


如今咱們使用Border Class代替Border.all。Border Class總共有4個參數top,bottom,left, right。每一個參數的值是BorderSide Class。 代碼以下:

//Border Property
//Border
class Border_Border_Property_Widget extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        width: 300.0,
        height: 300.0,
        color: Colors.white,
        child: Container(
          decoration: BoxDecoration(
            border: Border(
              top: BorderSide(
                color: Colors.green,
                width: 5.0,
                style: BorderStyle.solid
              )
            ),
            image: DecorationImage(
                image:AssetImage("images/JL-Logo-150.png")
            )
          ),
        ),
      ),
    );
  }
}
複製代碼

效果圖以下:

圖60 Border


如今使用一下BorderDirectional。 BorderDirectional和Border Class相似,有4個參數,可是沒有left和right,取而代之的是start和end。 代碼以下:

//Border Property
//BorderDirectional
class Border_BorderDirectional_Property_Widget extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        width: 300,
        height: 300,
        color: Colors.white,
        child: Container(
          decoration: BoxDecoration(
            border: BorderDirectional(
              top: BorderSide(
                color: Colors.green,
                width: 5.0,
                style: BorderStyle.solid
              ),
              start: BorderSide(
                color: Colors.green,
                width: 5.0,
                style: BorderStyle.solid
              )
            ),
            image: DecorationImage(
              image:AssetImage("images/JL-Logo-150.png")
            )    
          ),
        ),
      ),
    );
  }
}
複製代碼

效果圖以下:

圖61 BorderDirectional


11、borderRadius Property

若是你想容器四周出現圓角,你可使用borderRadius。

注意: borderRadius只適用於矩形形狀的盒子。

對應的取值是BorderRadius.all、BorderRadius.only、BorderRadius.circular、BorderRadius.horizontal、BorderRadius.vertical。

一樣你可使用BorderRadiusDirectional代替BorderRadius,可是參數裏面會將left和right替換爲start和end。

BorderRadius.all

代碼以下:

//borderRadius Property
//BorderRadius.all
class borderRadius_Property_Widget extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        width: 300.0,
        height: 300.0,
        color: Colors.white,
        child: Container(
          decoration: BoxDecoration(
            border: Border.all(
              color: Colors.green,
              width: 5.0,
              style: BorderStyle.solid
            ),
            borderRadius:BorderRadius.all(Radius.circular(20.0)),
            image: DecorationImage(
                image:AssetImage("images/JL-Logo-150.png")
            )
          ),
        ),
      ),
    );
  }
}
複製代碼

效果圖以下:

圖62 Border.all


如今來使用一下BorderRadius.circular 代碼以下;

//borderRadius Property
//BorderRadius.circular
class borderRadius_Property_Widget extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        width: 300.0,
        height: 300.0,
        color: Colors.white,
        child: Container(
          decoration: BoxDecoration(
            border: Border.all(
              color: Colors.green,
              width: 5.0,
              style: BorderStyle.solid
            ),
            //borderRadius:BorderRadius.all(Radius.circular(20.0)),
            borderRadius:BorderRadius.circular(20.0),
            image: DecorationImage(
                image:AssetImage("images/JL-Logo-150.png")
            )
          ),
        ),
      ),
    );
  }
}
複製代碼

效果圖以下:

圖63 BorderRadius.circular


由上面圖能夠知道,BorderRadius.circular和BorderRadius.all效果一致,不過BorderRadius.circular能夠直接輸入浮點型數據。

BorderRadius.horizontal

BorderRadius.horizontal會建立一個水平對稱的邊框半徑,其中矩形框的左右兩側具備相同的半徑。 代碼以下:

//borderRadius Property
//BorderRadius.horizontal
class BorderRadius_horizontal_Widget extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        width: 300.0,
        height: 300.0,
        color: Colors.white,
        child: Container(
          decoration: BoxDecoration(
            border: Border.all(
              color: Colors.green,
              width: 5.0,
              style: BorderStyle.solid
            ),
            borderRadius: BorderRadius.horizontal(
              left: Radius.circular(20.0),
              //right: new Radius.circular(20.0),
            ),
            image: DecorationImage(
                image: AssetImage("images/JL-Logo-150.png")
            )
          ),
        ),
      ),
    );
  }
}
複製代碼

效果圖以下:

圖64 BorderRadius.horizontal


BorderRadius.vertical

BorderRadius.vertical會建立一個垂直對稱的邊框半徑,其中矩形的上下兩側具備相同的半徑 代碼以下:

//borderRadius Property
//BorderRadius.vertical
class BorderRadius_vertical_Widget extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        width: 300.0,
        height: 300.0,
        color: Colors.white,
        child: Container(
          decoration: BoxDecoration(
            border: Border.all(
              color: Colors.green,
              width: 5.0,
              style: BorderStyle.solid
            ),
            borderRadius: BorderRadius.vertical(
              top: Radius.circular(20.0),
              //bottom: new Radius.circular(20.0),
            ),
            image: DecorationImage(
                image: AssetImage("images/JL-Logo-150.png"),
            )  
          ),
        ),
      ),
    );
  }
}
複製代碼

效果圖以下:

圖65 BorderRadius.vertical


BorderRadius.only

BorderRadius.only僅建立包含非零值的邊框半徑。其它角則是直角。 代碼以下:

//borderRadius Property
//BorderRadius.only
class BorderRadius_only_Widget extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        width: 300.0,
        height: 300.0,
        color: Colors.white,
        child: Container(
          decoration: BoxDecoration(
            border: Border.all(
              color: Colors.green,
              width: 5.0,
              style: BorderStyle.solid
            ),
            borderRadius: BorderRadius.only(
              topLeft: Radius.circular(20.0),
              //topRight: Radius.circular(20.0),
              bottomRight: Radius.circular(20.0),
              //bottomLeft: Radius.circular(20.0),
            ),
            image: DecorationImage(
                image:AssetImage("images/JL-Logo-150.png")
            )  
          ),
        ),
      ),
    );
  }
}
複製代碼

效果圖以下:

圖66 BorderRadius.only


另外,你也可使用Radius.elliptical代替Radius.circular。Radius.elliptical有2個參數(x,y)。 代碼以下:

//borderRadius Property
//Radius.elliptical
class Radius_elliptical_Widget extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return Center(
        child: Container(
          width: 300.0,
          height: 300.0,
          color: Colors.white,
          child: Container(
            decoration: BoxDecoration(
              border: Border.all(
                color: Colors.green,
                width: 5.0,
                style: BorderStyle.solid
              ),
              borderRadius: BorderRadius.only(
                 topLeft: Radius.elliptical(40.0, 10.0),
                 //topRight: Radius.circular(20.0),
                 bottomRight: Radius.circular(20.0),
                 //bottomLeft: Radius.circular(20.0),
              ),
              image: DecorationImage(
                  image:AssetImage("images/JL-Logo-150.png")
              )
            ),
          ),
        ),
    );
  }
}
複製代碼

效果圖以下:

圖67 Radius.elliptical


12、boxShadow Property

這個用於設置盒子的陰影,這個陰影和盒子的形狀保持一致。 boxShadow的值是一個包含BoxShadow的列表。你能夠在列表中使用multiple BoxShadow

BoxShadow有下面4個參數

  • color:陰影的顏色
  • offset:陰影相對於盒子的偏移量
  • blurRadius:高斯的標準誤差與盒子的形狀卷積。
  • spreadRadius:在應用模糊以前,框應該膨脹的量。

第一個例子咱們使用color和offset。 offset參數的值是一個Offset類,而且有2個浮點型參數x和y。 代碼以下:

//boxShadow Property
//color和offset
class boxShadow_colorAndoffset_Property_Widget extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        width: 200.0,
        height: 200.0,
        color: Colors.white,
        child: Container(
          decoration: BoxDecoration(
            color: Colors.white,
            border: Border.all(
              color: Colors.green,
              width: 5.0,
              style: BorderStyle.solid
            ),
            borderRadius: BorderRadius.only(
              topLeft: Radius.elliptical(40.0, 10.0),
              bottomLeft: Radius.circular(20.0),
            ),
            boxShadow: [
              BoxShadow(
                color: Colors.red,
                offset: Offset(20.0, 10.0)
              )
            ],
            image: DecorationImage(
                image:AssetImage("images/JL-Logo-150.png")
            )
          ),
        ),
      ),
    );
  }
}
複製代碼

效果圖以下:

圖68 boxShadow

上圖咱們將陰影沿X軸平移20,沿Y軸平移10。這個陰影是實體的。

這裏咱們添加blurRadius屬性,讓它成爲一個真正的陰影。 代碼以下:

//boxShadow Property
//blurRadius
class boxShadow_blurRadius_Property_Widget extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        width: 300.0,
        height: 300.0,
        color: Colors.white,
        child: Container(
          decoration: BoxDecoration(
            color: Colors.white,
            border: Border.all(
              color: Colors.green,
              width: 5.0,
              style: BorderStyle.solid
            ),
            borderRadius: BorderRadius.only(
              topLeft: Radius.elliptical(40.0, 10.0),
              bottomLeft: Radius.circular(20.0),
            ),
            boxShadow: [
              BoxShadow(
                color: Colors.red,
                offset: Offset(20.0, 10.0),
                blurRadius: 20.0,
              )
            ],
            image: DecorationImage(
                image: AssetImage("images/JL-Logo-150.png")
            )
          ),
        ),
      ),
    );
  }
}
複製代碼

效果圖以下:

圖69 blurRadius

如今將陰影進一步擴散。咱們將使用spreadRadius。 代碼以下:

//boxShadow Property
//spreadRadius
class boxShadow_spreadRadius_Property_Widget extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        width: 300.0,
        height: 300.0,
        color: Colors.white,
        child: Container(
          decoration: BoxDecoration(
            color: Colors.white,
            border: Border.all(
              color: Colors.green,
              width: 5.0,
              style: BorderStyle.solid
            ),
            borderRadius: BorderRadius.only(
              topLeft: Radius.elliptical(40.0, 10.0),
              bottomLeft: Radius.circular(20.0),
            ),
            boxShadow: [
              BoxShadow(
                color: Colors.red,
                offset: Offset(20.0, 10.0),
                blurRadius: 20.0,
                spreadRadius: 40.0,
              )
            ],
            image: DecorationImage(
                image:AssetImage("images/JL-Logo-150.png")
            )
          ),
        ),
      ),
    );
  }
}
複製代碼

效果圖以下:

圖70 spreadRadius

如今咱們使用多種BoxShadow。 代碼以下:

//boxShadow Property
//multiple BoxShadow
class boxShadow_multipleAndBoxShadow_Property_Widget extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        width: 300.0,
        height: 300.0,
        color: Colors.white,
        child: Container(
          decoration: BoxDecoration(
              color: Colors.white,
              border: Border.all(
                  color: Colors.green,
                  width: 5.0,
                  style: BorderStyle.solid
              ),
              borderRadius: BorderRadius.only(
                topLeft: Radius.elliptical(40.0, 10.0),
                bottomLeft: Radius.circular(20.0),
              ),
              boxShadow: [
                BoxShadow(
                  color: Colors.red,
                  offset: Offset(20.0, 10.0),
                  blurRadius: 20.0,
                  spreadRadius: 40.0,
                ),
                BoxShadow(
                  color: Colors.yellow,
                  offset: Offset(20.0, 10.0),
                  blurRadius: 20.0,
                  spreadRadius: 20.0,
                ),
                BoxShadow(
                  color: Colors.green,
                  offset: Offset(10.0, 5.0),
                  blurRadius: 20.0,
                  spreadRadius: 5.0,
                )
              ],
              image: DecorationImage(
                  image:AssetImage("images/JL-Logo-150.png")
              )
          ),
        ),
      ),
    );
  }
}
複製代碼

效果圖以下:

圖71 multiple BoxShadow

十3、shape Property

用於設置圖片形狀。 shape屬性值是枚舉類型的BoxShape。

  • BoxShape.rectangle
  • BoxShape.circle **注意:**若是值是BoxShape.circle,那麼borderRadius將無效。 代碼以下:
//shape Property
class shape_Property_Widget extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container(
        width: 300.0,
        height: 300.0,
        child: Container(
          decoration: BoxDecoration(
            color: Colors.white,
            border: Border.all(
              color: Colors.green,
              width: 5.0,
              style: BorderStyle.solid
            ),
            boxShadow: [
              BoxShadow(
                color: Colors.red,
                offset: Offset(20.0, 10.0),
                blurRadius: 20.0,
                spreadRadius: 40.0
              )
            ],
            shape: BoxShape.circle,
            image: DecorationImage(
                image: AssetImage("images/JL-Logo-150.png")
            )
          ),
        ),
      ),
    );
  }
}
複製代碼

效果圖以下:

圖72 shape

十4、Padding Property

請查看Flutter之Container用法詳解

參考文章

Flutter — BoxDecoration Cheat Sheet

相關文章
相關標籤/搜索