1 基本內容
1.1 繼續關係
Object > Diagnosticable > DiagnosticableTree > Widget > StatelessWidget > Container
注:所有控件都是Widget的子類!
1.2 介紹
一個便利的控件,結合了常見的繪畫,定位和大小調整。
1.3 行爲
由於Container結合了許多其他Widget,每個Widget都有自己的佈局行爲,因此Container的佈局行爲有點複雜。
依次是:
1.採用alignment
2.以child調整自身大小
3. 採用了width,height和constraints
4.擴大以適應父Widget
5.要儘可能小
具體情況來說:
1· 如果Container沒有子Widget,沒有height,沒有width,沒有constraints,並且父窗口提供無限制約束,則Container嘗試儘可能小。
2· 如果Container沒有子Widget,沒有alignment,而是一個height,width或 constraints提供,Container試圖給出這些限制和父Widget的約束相結合,以儘可能小。
3· 如果Container沒有子Widget,沒有height,沒有width,沒有constraints,沒有alignment,但是父窗口提供了有界約束,那麼Container會擴展以適應父窗口提供 的約束。
4· 如果Container具有alignment,並且父窗口提供無限制約束,則constraints會嘗試圍繞子Widget的alignment自身大小。
5· 如果Container具有alignment,並且父窗口提供有界約束,則constraints會嘗試展開以適合父窗口,然後根據alignment將子項置於其自身內。
6· Container具有子Widget,但沒有height,沒有width,沒有constraints,沒有alignment,將父級constraints傳遞給子級,自身調整大小。
2 構造方法講解
Container({
Key key,
this.alignment,
this.padding,
Color color,
Decoration decoration,
this.foregroundDecoration,
double width,
double height,
BoxConstraints constraints,
this.margin,
this.transform,
this.child,
}) : assert(margin == null || margin.isNonNegative),
assert(padding == null || padding.isNonNegative),
assert(decoration == null || decoration.debugAssertIsValid()),
assert(constraints == null || constraints.debugAssertIsValid()),
assert(color == null || decoration == null,
'Cannot provide both a color and a decoration\n'
'The color argument is just a shorthand for "decoration: new BoxDecoration(color: color)".'
)
各參數詳解
2.1 Key key:
您可以使用key來控制框架將在widget重建時與哪些其他widget匹配。默認情況下,框架根據它們的runtimeType和它們的顯示順序來匹配。 使用key時,框架要求兩個widget具有相同的key和runtimeType。
Key在構建相同類型widget的多個實例時很有用。例如,List構建足夠的ListItem實例以填充其可見區域:
如果沒有key,當前構建中的第一個條目將始終與前一個構建中的第一個條目同步,即使在語義上,列表中的第一個條目如果滾動出屏幕,那麼它將不會再在窗口中可見。
通過給列表中的每個條目分配爲“語義” key,無限列表可以更高效,因爲框架將同步條目與匹配的語義key並因此具有相似(或相同)的可視外觀。 此外,語義上同步條目意味着在有狀態子widget中,保留的狀態將附加到相同的語義條目上,而不是附加到相同數字位置上的條目。
2.2 AlignmentGeometry alignment:
如果父Widget尺寸大於child Widget尺寸,這個屬性設置會起作用,有很多種對齊方式。
AlignmentGeometry 是個抽象類
Alignment與AlignmentDirectional一樣的,只是命名不一樣,如Alignment中的topLeft跟AlignmentDirectional中的topStart一致。
Alignment主要以下對齊方式:
/// The top left corner.
static const Alignment topLeft = Alignment(-1.0, -1.0);
/// The center point along the top edge.
static const Alignment topCenter = Alignment(0.0, -1.0);
/// The top right corner.
static const Alignment topRight = Alignment(1.0, -1.0);
/// The center point along the left edge.
static const Alignment centerLeft = Alignment(-1.0, 0.0);
/// The center point, both horizontally and vertically.
static const Alignment center = Alignment(0.0, 0.0);
/// The center point along the right edge.
static const Alignment centerRight = Alignment(1.0, 0.0);
/// The bottom left corner.
static const Alignment bottomLeft = Alignment(-1.0, 1.0);
/// The center point along the bottom edge.
static const Alignment bottomCenter = Alignment(0.0, 1.0);
明顯看出構造方法中的二個參數範圍在[-1.0,1.0] 表示從頂部到底部或者從左到右
比如,想讓child在居中Alignment(0.0, 0.0)
FractionalOffset繼承Alignment
FractionalOffset構造方法可以看出,方法中的二個參數範圍在[0.0,1.0]表示從頂部到底部或者從左到右
const FractionalOffset(double dx, double dy)
: assert(dx != null),
assert(dy != null),
super(dx * 2.0 - 1.0, dy * 2.0 - 1.0);
2.3 EdgeInsetsGeometry padding:
內邊距:本Widget邊框和內容區之間距離。
EdgeInsetsGeometry 是個抽象類:
同理:EdgeInsetsDirectional與EdgeInsets功能一致!
EdgeInsets比EdgeInsetsDirectional多了一個方法:
const EdgeInsets.all(double value)
: left = value, top = value, right = value, bottom = value;
他們的常用方法
const EdgeInsets.fromLTRB(this.left, this.top, this.right, this.bottom);
const EdgeInsetsDirectional.fromSTEB(this.start, this.top, this.end, this.bottom);
注意的是,四個參數都不能有負數
因爲:限定了 assert(padding == null || padding.isNonNegative)
2.4 Color color:
Container背景色
一般通過 const Color(int value) : value = value & 0xFFFFFFFF; 創建對象,也可以使用Colors類中的靜態成員,從value & 0xFFFFFFFF可看出,默認值會不透明的。
注意:
用來設置container背景色,如果foregroundDecoration設置的話,可能會遮蓋color效果。
container背景色和decoration不能同時設置,
因爲:Container構造方法限定了assert(color == null || decoration == null,
'Cannot provide both a color and a decoration\n'
'The color argument is just a shorthand for "decoration: new BoxDecoration(color: color)".'
)
2.5 Decoration decoration:
繪製背景圖案。
將在下一篇文章中詳細講解Decoration (邊框、圓角、陰影、形狀、漸變、背景圖像)
注意:
container背景色和decoration不能同時設置
2.6 Decoration foregroundDecoration:
decoration是背景,foregroundDecoration是前景。設置了foregroundDecoration可能會遮蓋child內容,一般半透明遮蓋(蒙層)效果使用!
將在下一篇文章中詳細講解Decoration (邊框、圓角、陰影、形狀、漸變、背景圖像等等)
2.7 width、height
width:container的寬度,設置爲double.infinity可以強制在寬度上撐滿,不設置,則根據child和父節點兩者一起佈局。
height:container的高度,設置爲double.infinity可以強制在高度上撐滿。
2.8 BoxConstraints constraints:
添加到child上額外的約束條件。
const BoxConstraints({
this.minWidth = 0.0,
this.maxWidth = double.infinity,
this.minHeight = 0.0,
this.maxHeight = double.infinity
});
明顯是來設置child的寬高範圍值。還有很多靜態方法,不一一列出,看源碼即可!
注意:
0.0表示最小,double.infinity爲無限大
2.9 EdgeInsetsGeometry margin:
外邊距:本Widget與父邊框的距離。
值與padding一致。
2.10 Matrix4 transform:
4D Matrix(矩陣)後面文章會詳解
3.0 Widget child:
控件內容widget。
3 效果及示例
代碼:
import 'package:flutter/material.dart';
void main() {
runApp(new MaterialApp(
title: 'My app', // used by the OS task switcher
home: new MyStartUI(),
));
}
class MyStartUI extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new Container(
constraints: new BoxConstraints.expand(
height:Theme.of(context).textTheme.display1.fontSize * 1.1 + 200.0,
),
decoration: new BoxDecoration(
border: new Border.all(width: 2.0, color: Colors.red),
color: Colors.grey,
borderRadius: new BorderRadius.all(new Radius.circular(20.0)),
image: new DecorationImage(
image: new NetworkImage('https://avatar.csdn.net/8/9/A/3_chenlove1.jpg'),
centerSlice: new Rect.fromLTRB(270.0, 180.0, 1360.0, 730.0),
),
),
padding: const EdgeInsets.all(5.0),
margin: const EdgeInsets.all(10.0),
alignment: Alignment.center,
child: new Text('Ying You Learning',
style: Theme.of(context).textTheme.display1.copyWith(color: Colors.red)),
transform: new Matrix4.rotationZ(0.0),
);
}
}
4 學習來自
1.https://docs.flutter.io/flutter/widgets/Container-class.html
2.Dart源碼