使用Flutter的視覺,結構,平臺和交互式小部件集合更快地建立漂亮的應用程序。html
基本部件java
在構建您的第一個Flutter應用程序以前,您絕對須要瞭解這些小部件。算法
一個方便的小部件,結合了常見的繪畫,定位和尺寸小部件。數組
一個容器首先用padding包圍子組件(由decoration中出現的全部邊框填滿),而後將附加constraints應用於填充範圍(將width和height做爲約束合併(若是其中任一個非空)。而後container被 margin描述的額外的空白空間包圍。app
在繪製過程當中,容器首先應用給定的transform,而後繪製decoration來填滿填充範圍,而後繪製子組件,最後繪製foregroundDecoration,並填滿填充範圍。框架
沒有子組件的容器儘量大,除非傳入的約束是無限的。在這種狀況下,他們儘量小,有子組件的容器將本身的尺寸擴大到他們的孩子大小,構造函數的寬度,高度和constraints參數將覆蓋這些。less
佈局行爲ide
有關Box佈局模型的介紹,請參閱BoxConstraints(盒修飾)。函數
因爲Container將許多其它部件與各自的佈局行爲結合在一塊兒,所以Container的佈局行爲有點複雜。工具
Container按順序嘗試:遵照alignment,將本身調整到child部件的尺寸,遵照寬度,高度和constraints,擴展以適應父部件,變得儘量小。
進一步來講:
若是部件沒有子,沒有height,沒有width,沒有constraints(對子部件的約束),父母提供了無界限的約束,那麼Container嘗試儘量小。
若是部件沒有子且沒有alignment(對齊),可是提供了高度,寬度或constraints(約束),那麼基於給定這些約束和父對象的約束相結合容器會嘗試儘量小。
若是小部件沒有孩子,沒有高度,沒有寬度,沒有約束,也沒有對齊,但父級提供有界的約束,則Container展開以適應父級提供的約束。
若是部件具備alignment,而且父級提供了無界的約束,那麼容器會嘗試圍繞該子部件調整本身的大小。
若是部件有alignment,而且父級提供了有界限的約束,那麼容器會嘗試展開以適合父級,而後根據alignment將該子級定位到其自身內。
另外,部件有一個子部件,但沒有高度,沒有寬度,沒有約束,也沒有對齊,而且容器將約束從父項傳遞給子項,並將其自身尺寸設置爲與子部件匹配。
如這些屬性的文檔中所述,margin和padding屬性也會影響佈局。 (它們的效果只是豐富了上述規則。)decoration能夠隱式強化填充(例如,BoxDecoration中的邊框有助於填充); 請參閱Decoration.padding。
示例代碼
這個例子顯示了一個48x48的綠色正方形(放置在一個Center部件中,以防父容器對Container應該採用的尺寸有本身的見解),並帶有一個邊距,以便它遠離相鄰的小部件:
new Center( child: new Container( margin: const EdgeInsets.all(10.0), color: const Color(0xFF00FF00), width: 48.0, height: 48.0, ), )
此示例顯示如何一次使用Container的許多功能。constraints被設置爲適合字體大小加上充足的頭部垂直空間,同時水平擴展以適合父母。padding用於確保內容和文本之間有空間。 顏色使箱子藍綠色。alignment使得子部件被置於框中。foregroundDecoration將九個斑點的圖像疊加到文本上。最後,transform對整個裝置施加輕微旋轉以完成效果。
new Container( constraints: new BoxConstraints.expand( height: Theme.of(context).textTheme.display1.fontSize * 1.1 + 200.0, ), padding: const EdgeInsets.all(8.0), color: Colors.teal.shade700, alignment: Alignment.center, child: new Text('Hello World', style: Theme.of(context).textTheme.display1.copyWith(color: Colors.white)), foregroundDecoration: new BoxDecoration( image: new DecorationImage( image: new NetworkImage('https://www.example.com/images/frame.png'), centerSlice: new Rect.fromLTRB(270.0, 180.0, 1360.0, 730.0), ), ), transform: new Matrix4.rotationZ(0.1), )
也能夠看看:
繼承結構
Object>Diagnosticable>DiagnosticableTree>Widget>StatelessWidget>Container
構造器
Container({Key key, AlignmentGeometry alignment, EdgeInsetsGeometry padding, Color color, Decoration decoration, Decoration foregroundDecoration, double width, double height, BoxConstraints constraints, EdgeInsetsGeometry margin, Matrix4 transform, Widget child })
建立一個結合常見繪畫,定位和尺寸小部件的小部件。[...]
屬性
將容器內的子部件對齊。[...]
final
容器中包含的子部件。[...]
final
應用於子部件的附加限制。[...]
final
繪製子部件背景裝飾。[...]
final
foregroundDecoration → Decoration
繪製子部件前景裝飾。
final
圍繞裝飾和子部件的空的區域。
final
在裝飾裏面刻寫的空的區域。 子部件,若是有的話,被放置在這個填充。 [...]
final
繪製容器以前應用的轉換矩陣。
final
此對象的哈希碼. [...]
read-only, inherited
控制一個部件如何替換樹中的另外一個部件。 [...]
final, inherited
對象的運行時類型的表示。
read-only, inherited
方法
build(BuildContext context) → Widget
介紹由此部件表明的用戶界面的一部分. [...]
debugFillProperties(DiagnosticPropertiesBuilder description) → void
createElement() → StatelessElement
建立一個StatelessElement來管理該小部件在樹中的位置. [...]
inherited
debugDescribeChildren() → List<DiagnosticsNode>
返回描述此節點的子節點的DiagnosticsNode對象的列表. [...]
@protected, inherited
noSuchMethod(Invocation invocation) → dynamic
當訪問不存在的方法或屬性時調用. [...]
inherited
toDiagnosticsNode({String name, DiagnosticsTreeStyle style }) → DiagnosticsNode
返回調試工具和toStringDeep使用的對象的調試表示形式. [...]
inherited
toString({DiagnosticLevel minLevel: DiagnosticLevel.debug }) → String
返回此對象的字符串表示形式.
inherited
toStringDeep({String prefixLineOne: '', String prefixOtherLines, DiagnosticLevel minLevel: DiagnosticLevel.debug }) → String
返回此節點及其後代的字符串表示形式. [...]
inherited
toStringShallow({String joiner: ',', DiagnosticLevel minLevel: DiagnosticLevel.debug }) → String
返回對象的單行詳細描述. [...]
inherited
toStringShort() → String
這個部件的簡短的文字描述.
inherited
操做符
operator ==(other) → bool
相等運算符. [...]
inherited
在水平方向上佈局子部件的列表。
一個以水平數組顯示其子項的部件。
要讓孩子展開以填充可用的水平空間,請將該孩子包裹在Expanded部件中。
Row部件不會滾動(而且通常認爲在一行中有更多的孩子比適合可用的房間更好是錯誤的)。若是您有一行小部件,並但願它們在空間不足的狀況下可以滾動,請考慮使用ListView。
對於垂直變體,請參見Column。
若是你只有一個子組件,那麼考慮使用Align或Center來定位子組件。
示例代碼
此示例將可用空間劃分爲三個(水平),並將文本居中放置在前兩個單元格中,並將Flutter徽標放在第三個單元格中央:
new Row( children: <Widget>[ new Expanded( child: new Text('Deliver features faster', textAlign: TextAlign.center), ), new Expanded( child: new Text('Craft beautiful UIs', textAlign: TextAlign.center), ), new Expanded( child: new FittedBox( fit: BoxFit.contain, // otherwise the logo will be tiny child: const FlutterLogo(), ), ), ], )
疑難解答
爲何個人行有黃色和黑色的警告條紋?
若是該行的非彈性內容比該行(那些不包含在Expanded或Flexible部件中的)自己多,則該行被認爲已經溢出。當一行溢出時,該行沒有任何剩餘空間Expanded和Flexible的子項。該行經過在溢出的邊上繪製黃色和黑色條紋警告來報告此狀況。若是行外有空間,溢出量將以紅色字體打印。
故事時間
假設,例如,你有這樣的代碼:
new Row( children: <Widget>[ const FlutterLogo(), const Text('Flutter\'s hot reload helps you quickly and easily experiment, build UIs, add features, and fix bug faster. Experience sub-second reload times, without losing state, on emulators, simulators, and hardware for iOS and Android.'), const Icon(Icons.sentiment_very_satisfied), ], )
該行首先詢問其第一個子部件FlutterLogo佈局,以任何尺寸標識。該徽標是友好的,愉快地決定一邊24像素。這爲下一個子部件留下了不少空間。該行而後詢問下一個子部件,文本,它認爲最好的尺寸佈局。
在這一點上,不知道有多寬的文字會超出,說:「Ok, I will be thiiiiiiiiiiiiiiiiiiiis wide.」,而且遠遠超出了該行可用的空間,而不是包裹。行反應,「That's not fair, now I have no more room available for my other children!」,並生氣發芽,黃色和黑色的條幅。
解決方法是將第二個孩子包裝在Expanded部件中,該部件告訴行該子部件應該給予剩餘房間:
new Row( children: <Widget>[ const FlutterLogo(), const Expanded( child: const Text('Flutter\'s hot reload helps you quickly and easily experiment, build UIs, add features, and fix bug faster. Experience sub-second reload times, without losing state, on emulators, simulators, and hardware for iOS and Android.'), ), const Icon(Icons.sentiment_very_satisfied), ], )
如今,該行首先要求logo佈局,而後要求該icon佈局。象標誌同樣,Icon很樂意採用合理的尺寸(也是24像素,並不是巧合,由於FlutterLogo和Icon都符合環境IconTheme)。這留下了一些空間,如今該行告訴文本究竟有多寬:剩餘空間的確切寬度。該文本如今很樂意遵照合理的請求,將文本包裝在該寬度內,而且最終將一段文字分紅幾行。
佈局算法
本節介紹框架如何渲染Row。 有關Box佈局模型的介紹,請參閱BoxConstraints。
一行的佈局分六步進行:
也能夠看看:
繼承結構
Object>Diagnosticable>DiagnosticableTree>Widget>RenderObjectWidge>MultiChildRenderObjectWidget>Flex>Row
構造函數
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 [] })
建立一個水平的子部件數組。[...]
屬性
樹中的部件下面的部件. [...]
final, inherited
crossAxisAlignment → CrossAxisAlignment
子部件應該如何沿着橫軸放置. [...]
final, inherited
用做主軸的方向. [...]
final, inherited
此對象的哈希碼. [...]
read-only, inherited
控制一個部件如何替換樹中的另外一個部件. [...]
final, inherited
mainAxisAlignment → MainAxisAlignment
子部件應該如何沿主軸放置. [...]
final, inherited
在主軸上應占多少空間. [...]
final, inherited
對象的運行時類型的表示.
read-only, inherited
若是根據他們的基線對齊條目,使用哪一個基線.
final, inherited
肯定水平放置子部件的順序以及如何解釋水平方向的開始和結束. [...]
final, inherited
verticalDirection → VerticalDirection
肯定垂直放置子部件的順序以及如何解釋垂直方向的開始和結束. [...]
final, inherited
方法
createElement() → MultiChildRenderObjectElement
RenderObjectWidgets老是膨脹爲一個RenderObjectElement子類.
inherited
createRenderObject(BuildContext context) → RenderFlex
使用RenderObjectWidget描述的配置建立此RenderObjectWidget表示的RenderObject類的實例 . [...]
inherited
debugDescribeChildren() → List<DiagnosticsNode>
返回描述此節點的子節點的DiagnosticsNode對象的列表. [...]
@protected, inherited
debugFillProperties(DiagnosticPropertiesBuilder description) → void
inherited
didUnmountRenderObject(RenderObject renderObject) → void
先前與此部件關聯的呈現對象已從樹中移除。 給定的RenderObject將與此對象的createRenderObject返回的類型相同.
@protected, inherited
getEffectiveTextDirection(BuildContext context) → TextDirection
傳給RenderFlex.textDirection的值. [...]
@protected, inherited
noSuchMethod(Invocation invocation) → dynamic
當訪問不存在的方法或屬性時調用. [...]
inherited
toDiagnosticsNode({String name, DiagnosticsTreeStyle style }) → DiagnosticsNode
返回調試工具和toStringDeep使用的對象的調試表示形式. [...]
inherited
toString({DiagnosticLevel minLevel: DiagnosticLevel.debug }) → String
返回此對象的字符串表示形式.
inherited
toStringDeep({String prefixLineOne: '', String prefixOtherLines, DiagnosticLevel minLevel: DiagnosticLevel.debug }) → String
返回此節點及其後代的字符串表示形式. [...]
inherited
toStringShallow({String joiner: ', ', DiagnosticLevel minLevel: DiagnosticLevel.debug }) → String
返回對象的單行詳細描述. [...]
inherited
toStringShort() → String
這個部件的簡短的文字描述.
inherited
updateRenderObject(BuildContext context, RenderFlex renderObject) → void
將此RenderObjectWidget描述的配置複製到給定的RenderObject,該RenderObject與該對象的createRenderObject返回的類型相同 . [...]
inherited
操做符
operator ==(other) → bool
等值操做符. [...]
inherited
以垂直陣列顯示其子項的部件。
要讓子部件擴大以填充可用的垂直空間,請將該子部件包裝在Expanded部件中。
Column部件不滾動(而且一般認爲寧願在列中有更多子項也不使用適合可用空間是錯誤的)。 若是您有一行小部件,並但願它們在空間不足的狀況下可以滾動,請考慮使用ListView。
對於水平變體,請參見Row。
若是隻有一個子部件,那麼考慮使用Align或Center來定位子部件。
示例代碼
這個例子使用一個Column垂直排列三個部件,最後一個用來填充全部剩餘的空間。
new Column( children: <Widget>[ new Text('Deliver features faster'), new Text('Craft beautiful UIs'), new Expanded( child: new FittedBox( fit: BoxFit.contain, // otherwise the logo will be tiny child: const FlutterLogo(), ), ), ], )
在上面的示例中,text和logo位於每行的中心。在如下示例中,crossAxisAlignment設置爲CrossAxisAlignment.start,以便子部件左對齊。mainAxisSize被設置爲MainAxisSize.min,以便該列縮小以適合子部件。
new Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: <Widget>[ new Text('We move under cover and we move as one'), new Text('Through the night, we have one shot to live another day'), new Text('We cannot let a stray gunshot give us away'), new Text('We will fight up close, seize the moment and stay in it'), new Text('It’s either that or meet the business end of a bayonet'), new Text('The code word is ‘Rochambeau,’ dig me?'), new Text('Rochambeau!', style: DefaultTextStyle.of(context).style.apply(fontSizeFactor: 2.0)), ], )
故障排除
當傳入的垂直約束是無界的時候
當一個列有一個或多個Expanded或Flexible的子元素,而且被放置在另外一列,或者在一個ListView中,或者在其它沒有爲該列提供最大高度限制的上下文中時,你會在運行時說這個異常存在彈性子部件,但垂直約束是無界的。
這個例外所伴隨的細節中所描述的問題是,使用Flexible或Expanded意味着在佈置全部其餘子部件以後的剩餘空間必須平等地共享,可是若是傳入的垂直約束是無限的,則剩餘空間有無限空間。
解決這個問題的關鍵一般是肯定爲何Column正在接收無界的垂直約束。
發生這種狀況的一個常見緣由是列已被放置在另外一列中(沒有使用Expanded或Flexible圍繞內部嵌套列)。當一個列布局它的非柔性子部件(那些既沒有 Expanded也沒有Flexible包裹的子部件)時,它給了他們無限的約束,以便他們能夠肯定他們本身的尺寸(傳遞無界的約束一般指示子部件應該收縮包裹其內容)。在這種狀況下,解決方案一般只是將內部列包裝在Expanded中,以代表它應該佔用外部列的剩餘空間,而不只僅是它須要的空間。
顯示此消息的另外一個緣由是將列嵌套到ListView或其餘垂直滾動條中。在這種狀況下,確實存在無限的垂直空間(垂直滾動列表的整個點是容許垂直無限空間)。在這種狀況下,一般值得研究內部列爲何應該有一個Expanded或Flexible的子部件:內部子部件應該是多大?這種狀況下的解決方案一般是從內部子部件周圍移除Expanded或Flexible部件。
有關約束的更多討論,請參閱BoxConstraints。
黃色和黑色的條紋橫幅
當列的內容超過可用空間量時,列溢出,內容被剪輯。 在調試模式下,在溢出邊緣處呈現黃色和黑色條紋條以指示問題,並在列下方顯示一條消息,指出檢測到多少溢出。
一般的解決方案是使用ListView而不是Column來在垂直空間有限時使內容滾動。
佈局算法
本節介紹框架如何呈現一列。 有關Box佈局模型的介紹,請參閱BoxConstraints。
一列的佈局分六步進行:
也能夠看看:
繼承結構
Object>Diagnosticable>DiagnosticableTree>Widget>RenderObjectWidget>MultiChildRenderObjectWidget>Flex>Column
構造函數
Column({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 [] })
建立一個垂直的子部件數組. [...]
屬性,方法,操做符
同Row