Flutte部件目錄-基本部件(一)

使用Flutter的視覺,結構,平臺和交互式小部件集合更快地建立漂亮的應用程序。html

基本部件java

在構建您的第一個Flutter應用程序以前,您絕對須要瞭解這些小部件。算法

Container

一個方便的小部件,結合了常見的繪畫,定位和尺寸小部件。數組

一個容器首先用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將該子級定位到其自身內。

另外,部件有一個子部件,但沒有高度,沒有寬度,沒有約束,也沒有對齊,而且容器將約束從父項傳遞給子項,並將其自身尺寸設置爲與子部件匹配。

如這些屬性的文檔中所述,marginpadding屬性也會影響佈局。 (它們的效果只是豐富了上述規則。)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 })

建立一個結合常見繪畫,定位和尺寸小部件的小部件。[...]

屬性

alignment → AlignmentGeometry

將容器內的子部件對齊。[...]

final

child → Widget

容器中包含的子部件。[...]

final

constraints → BoxConstraints

應用於子部件的附加限制。[...]

final

decoration → Decoration

繪製子部件背景裝飾。[...]

final

foregroundDecoration → Decoration

繪製子部件前景裝飾。

final

margin → EdgeInsetsGeometry

圍繞裝飾和子部件的空的區域。

final

padding → EdgeInsetsGeometry

在裝飾裏面刻寫的空的區域。 子部件,若是有的話,被放置在這個填充。 [...]

final

transform → Matrix4

繪製容器以前應用的轉換矩陣。

final

hashCode → int

此對象的哈希碼. [...]

read-only, inherited

key → Key

控制一個部件如何替換樹中的另外一個部件。 [...]

final, inherited

runtimeType → Type

對象的運行時類型的表示。

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

Row 

在水平方向上佈局子部件的列表。

一個以水平數組顯示其子項的部件。

要讓孩子展開以填充可用的水平空間,請將該孩子包裹在Expanded部件中。

Row部件不會滾動(而且通常認爲在一行中有更多的孩子比適合可用的房間更好是錯誤的)。若是您有一行小部件,並但願它們在空間不足的狀況下可以滾動,請考慮使用ListView

對於垂直變體,請參見Column

若是你只有一個子組件,那麼考慮使用AlignCenter來定位子組件。

示例代碼

此示例將可用空間劃分爲三個(水平),並將文本居中放置在前兩個單元格中,並將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(),
      ),
    ),
  ],
)

疑難解答
爲何個人行有黃色和黑色的警告條紋?

若是該行的非彈性內容比該行(那些不包含在ExpandedFlexible部件中的)自己多,則該行被認爲已經溢出。當一行溢出時,該行沒有任何剩餘空間ExpandedFlexible的子項。該行經過在溢出的邊上繪製黃色和黑色條紋警告來報告此狀況。若是行外有空間,溢出量將以紅色字體打印。

故事時間
假設,例如,你有這樣的代碼:

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像素,並不是巧合,由於FlutterLogoIcon都符合環境IconTheme)。這留下了一些空間,如今該行告訴文本究竟有多寬:剩餘空間的確切寬度。該文本如今很樂意遵照合理的請求,將文本包裝在該寬度內,而且最終將一段文字分紅幾行。

佈局算法
本節介紹框架如何渲染Row。 有關Box佈局模型的介紹,請參閱BoxConstraints

一行的佈局分六步進行:

  1. 爲每一個孩子設置一個Null或0個彈性因子(例如,那些沒有擴大的因子),其中包含無界的水平約束和傳入的垂直約束。若是crossAxisAlignmentCrossAxisAlignment.stretch,則應使用與輸入最大高度相匹配的嚴格垂直約束。
  2. 根據彈性因子,劃分非零彈性因子(例如,Expanded)中的剩餘水平空間。例如,彈性係數爲2.0的孩子將得到兩倍於水平空間的彈性係數爲1.0的孩子。
  3. 使用與步驟1相同的垂直約束佈局每一個剩餘的子項,但不是使用無界的水平約束,而是使用基於步驟2中分配的空間量的水平約束。具備FlexFit.tightFlexible.fit屬性的孩子被給予嚴格的約束(即,被迫填充分配的空間),而且具備FlexFit.looseFlexible.fit屬性的孩子被給予寬鬆的約束(即,不被迫填充 分配空間)。
  4. Row的高度是子部件的最大高度(這將始終知足傳入的垂直約束)。
  5. 行的寬度由mainAxisSize屬性肯定。若是mainAxisSize屬性是MainAxisSize.max,則Row的寬度是傳入約束的最大寬度。 若是mainAxisSize屬性是MainAxisSize.min,則Row的寬度是子級寬度的總和(受到傳入約束的限制)。
  6. 根據mainAxisAlignmentcrossAxisAlignment肯定每一個子部件的位置。例如,若是mainAxisAlignmentMainAxisAlignment.spaceBetween,全部未分配給子部件的水平空間均勻劃分並放置在子部件之間。

也能夠看看:

  • Column,垂直等效。
  • Flex,若是您事先不知道是否須要水平或垂直佈置。
  • Expanded,以代表子部件應該使用全部剩餘房間。
  • Flexible,指示子部件應該共享剩餘房間,但可能小一些(留下一些剩餘房間未使用)。
  • 佈局部件的目錄

繼承結構

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 [] })

建立一個水平的子部件數組。[...]

屬性

children → List<Widget>

樹中的部件下面的部件. [...]

final, inherited

crossAxisAlignment → CrossAxisAlignment

子部件應該如何沿着橫軸放置. [...]

final, inherited

direction → Axis

用做主軸的方向. [...]

final, inherited

hashCode → int

此對象的哈希碼. [...]

read-only, inherited

key → Key

控制一個部件如何替換樹中的另外一個部件. [...]

final, inherited

mainAxisAlignment → MainAxisAlignment

子部件應該如何沿主軸放置. [...]

final, inherited

mainAxisSize → MainAxisSize

在主軸上應占多少空間. [...]

final, inherited

runtimeType → Type

對象的運行時類型的表示.

read-only, inherited

textBaseline → TextBaseline

若是根據他們的基線對齊條目,使用哪一個基線.

final, inherited

textDirection → TextDirection

肯定水平放置子部件的順序以及如何解釋水平方向的開始和結束. [...]

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

Column

以垂直陣列顯示其子項的部件。

要讓子部件擴大以填充可用的垂直空間,請將該子部件包裝在Expanded部件中。

Column部件不滾動(而且一般認爲寧願在列中有更多子項也不使用適合可用空間是錯誤的)。 若是您有一行小部件,並但願它們在空間不足的狀況下可以滾動,請考慮使用ListView

對於水平變體,請參見Row

若是隻有一個子部件,那麼考慮使用AlignCenter來定位子部件。

示例代碼
這個例子使用一個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)),
  ],
)

故障排除
當傳入的垂直約束是無界的時候

當一個列有一個或多個ExpandedFlexible的子元素,而且被放置在另外一列,或者在一個ListView中,或者在其它沒有爲該列提供最大高度限制的上下文中時,你會在運行時說這個異常存在彈性子部件,但垂直約束是無界的。

這個例外所伴隨的細節中所描述的問題是,使用FlexibleExpanded意味着在佈置全部其餘子部件以後的剩餘空間必須平等地共享,可是若是傳入的垂直約束是無限的,則剩餘空間有無限空間。

解決這個問題的關鍵一般是肯定爲何Column正在接收無界的垂直約束。

發生這種狀況的一個常見緣由是列已被放置在另外一列中(沒有使用ExpandedFlexible圍繞內部嵌套列)。當一個列布局它的非柔性子部件(那些既沒有 Expanded也沒有Flexible包裹的子部件)時,它給了他們無限的約束,以便他們能夠肯定他們本身的尺寸(傳遞無界的約束一般指示子部件應該收縮包裹其內容)。在這種狀況下,解決方案一般只是將內部列包裝在Expanded中,以代表它應該佔用外部列的剩餘空間,而不只僅是它須要的空間。

顯示此消息的另外一個緣由是將列嵌套到ListView或其餘垂直滾動條中。在這種狀況下,確實存在無限的垂直空間(垂直滾動列表的整個點是容許垂直無限空間)。在這種狀況下,一般值得研究內部列爲何應該有一個ExpandedFlexible的子部件:內部子部件應該是多大?這種狀況下的解決方案一般是從內部子部件周圍移除ExpandedFlexible部件。

有關約束的更多討論,請參閱BoxConstraints

黃色和黑色的條紋橫幅

當列的內容超過可用空間量時,列溢出,內容被剪輯。 在調試模式下,在溢出邊緣處呈現黃色和黑色條紋條以指示問題,並在列下方顯示一條消息,指出檢測到多少溢出。

一般的解決方案是使用ListView而不是Column來在垂直空間有限時使內容滾動。

佈局算法
本節介紹框架如何呈現一。 有關Box佈局模型的介紹,請參閱BoxConstraints

一列的佈局分六步進行:

  1. 爲每一個孩子設置一個null或零個彈性因子(例如那些沒有Expanded的部件)和無限制的垂直約束和傳入水平約束。若是crossAxisAlignmentCrossAxisAlignment.stretch,請使用與輸入最大寬度匹配的嚴格的水平約束。
  2. 根據彈性因子,在非零彈性因子的子部件(例如擴展)中劃分剩餘的垂直空間。 例如,彈性係數爲2.0的子部件將得到彈性係數爲1.0的子部件的兩倍的垂直空間量。
  3. 使用與步驟1中相同的水平約束來佈局每一個剩餘的子項,但不是使用無界的垂直約束,而是使用基於步驟2中分配的全部空間的垂直約束。Flexible.fit屬性是FlexFit.tight嚴格約束的子項(即,被迫填充分配的空間),而且具備FlexFit.looseFlexible.fit屬性的孩子被給予寬鬆的約束(即,不被迫填充分配的空間)。
  4. Column的寬度是子部件的最大寬度(這將始終知足傳入的水平約束)。
  5. 列的高度由mainAxisSize屬性肯定。若是mainAxisSize屬性爲MainAxisSize.max,那麼Column的高度就是傳入約束的最大高度。若是mainAxisSize屬性爲MainAxisSize.min,那麼Column的高度就是子級高度的總和(受傳入約束條件的影響)。
  6. 根據mainAxisAlignmentcrossAxisAlignment肯定每一個子部件的位置。例如,若是mainAxisAlignmentMainAxisAlignment.spaceBetween,則全部還沒有分配給子部件的垂直空間均勻劃分並放置在子部件之間。

也能夠看看:

  • Column,垂直等效。
  • Flex,若是您事先不知道是否須要水平或垂直佈置。
  • Expanded,以代表子部件應該使用全部剩餘房間。
  • Flexible,指示子部件應該共享剩餘房間,但可能小一些(留下一些剩餘房間未使用)。
  • 佈局部件的目錄

繼承結構

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

相關文章
相關標籤/搜索