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,
),
),
),
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"))),
),
),
圖檔并沒有充滿整個背景,用
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"))),
),
),
border
設定
Widget
的邊框樣式,設定方式為
Border.xxx
,
Border
為
BoxBorder
類型。
-
同時設定上下左右4條邊框的樣式,border.all(Color color, double width,BorderStyle style)
設定顔色,color
設定邊框寬度,width
設定邊框樣式,style
為style
枚舉類型,隻有BorderStyle
和none
兩個值。solid
表示無邊框,none
表示實線邊框。solid
的預設顔色是黑色,邊框寬度為1.0,樣式為border.all()
。BorderStyle.solid
把顔色設定為紅色,寬度設定為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,
)),
),
),
)
-
從參數可以看出,是分别設定垂直方向的邊框和水準方向的邊框,即Border.symmetric(BorderSide vertical, BorderSide horizontal)
設定上邊和下邊的邊框,vertical
horizontal
設定左邊和右邊的邊框。
參數是
,而BorderSide
的參數與BorderSide
的參數一樣,都是border.all
,是以設定方式應該是下面這樣的:Color color, double width,BorderStyle style
垂直方向上的邊框顔色為紅色,寬度為5.0,水準方向上的邊框顔色為藍色,寬度為10.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.symmetric( vertical: BorderSide( // 垂直方向(上、下) color: Colors.red, width: 5.0, ), horizontal: BorderSide( // 水準方向(左、右) color: Colors.blue, width: 10.0, )), ), ), ),
-
字面上的意思是從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, ))), ), ),
-
四條邊框分别設定,可以設定不同的樣式。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)), // 左側邊框 ), ), ),
borderRadius
設定邊框圓角,類型為
BorderRadiusGeometry
,設定方式為
BorderRadius.xxx
-
同時設定4個圓角,參數是BorderRadius.all(Radius radius)
,設定正圓角,則用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))), // 設定正圓角 ), ),
再試試設定橢圓角是什麼效果
borderRadius: BorderRadius.all(Radius.elliptical(10, 100))), // 設定橢圓角
試驗了很多次,貌似隻有在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,也可單獨設定左邊或右邊 ), ), ),
-
設定垂直方向上的圓角,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,也可單獨設定上邊或下邊 ), ), ),
-
單獨設定每個角的圓角效果。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)), ), ), ),
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
]),
),
),
上圖是沒有設定
Offset
偏移量,我們讓它向左上方各偏移20看看是什麼效果
BoxShadow( // 設定第一個陰影效果
color: Colors.green, // 陰影顔色為綠色
offset: Offset(-20, -20), // X軸左移20,Y軸上移20
blurRadius: 10, // 模糊半徑為10
spreadRadius: 10), // 延伸半徑為10
再看看設定兩個
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),
]),
),
),
可以看出,多個
BoxShadow
确實是疊加的效果,并且後面的
BoxShadow
會在之前的
BoxShadow
的上方。
對比一下兩個
BoxShadow
交換位置的效果
黃色陰影在上 | 綠色陰影在上 |
---|---|
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
-
漸變色的終止百分比位置的數組,可為空。如
[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],
),
),
),
),
從圖中可以不太容易看出來
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:綠色
-
begin
漸變顔色的起止位置,表示漸變色從end
位置開始,到begin
位置結束。她們都是end
類型,表示對齊方式。和AlignmentGeometry
的對齊方式Container
一樣,将一個alignment
分為了9個點(參考Container的對齊方式):Widget
預設的對齊方式是從左側中間到右側中間漸變,即從
(-1, 0)
到
(0 1)
。
如果将上例中的
begin
指定為
Alignment.bottomLeft
,
end
指定為
Alignment.topRight
,則漸變方向變成了從
左下角
往
右上角
漸變。
-
平鋪模式,共有三種模式,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
,剛好占據1/4,。(-0.5, 0)
TileMode.clamp | TileMode.repeated | TileMode.mirror |
---|---|---|
-
:放射漸變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], ), ), ), ),
-
将
center
的位置設定到右上角
-
掃描漸變區域半徑比例,預設為radius
,即矩形0.5
較短邊的一半。Widget
将
radius
設定成1,
- 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,為右側中間的位置。2π
-
結束漸變的弧度,預設值是endAngle
,還有一點就是2π
必須大于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),
),
),
),
漸變範圍從弧度為
π
到
2π
,是以真正的掃描漸變範圍在上面一半,下面一半紅色顯示的是開始顔色紅色。
現在我們把掃描範圍設定成從
到
3 * π/ 4
,再看看效果
從上面2個效果圖中可以看出來,在預設混合模式
TileMode.clamp
中,當掃描範圍不滿一周時,接近0弧度的區域填充的是
colors
中設定的起始顔色,越接近
2π
弧度的區域填充的是
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 |
---|---|---|