flutter widget:其他布局

1. Flex

如果你不確定需要具體的排列方向是水平還是垂直的時候,可以使用。(可以動態的根據不同的方向具體顯示?)他表示子節點會在一維方向上顯示。

Flex 允許你根據子節點的放置(水平或垂直)來控制軸。這被稱作主軸。你如果事先直到具體的主軸,那么考慮使用Row或者Column,因為這不這么冗余。

如果需要讓孩子展開填充可用的垂直空間,用Expanded包裹孩子。

實際上 ColumnRow 都是繼承 Flex,并且實現了具體的差異化。

2. Expanded

Expanded 可以展開 RowColumn,或者Flex的子結點。

使用Expanded可以讓RowColumnFlex的子節點展開來填充其主軸上的剩余可用空間(例如 Row的水平空間,Column的垂直空間)。如果多個子結點都被展開,則根據flex因子來分配的具體空間。

Expanded控件必須是RowColumnFlex的后代,從控件到其封閉的RowColumnFlex的路徑必須只包含StatelessWidgets 或StatefulWidget這些,不能是其他類型的Widget(例如RenderObjectWidget)。

3. Flexible

用于控制RowColumnFlex的伸縮值。

實際上Expanded是繼承 Flexible。使用Flexible小部件為RowColumnFlex的子部件提供了擴展以填充主軸中可用空間的靈活性(例如,水平地填充Row或垂直地填充Column),但與Expanded不同,Flexible不要求子部件填充可用空間。

Flexible控件必須是RowColumnFlex的后代,從控件到其封閉的RowColumnFlex的路徑必須只包含StatelessWidgets 或StatefulWidget這些,不能是其他類型的Widget(例如RenderObjectWidget)。

4. SingleChildScrollView

一個可以滾動單個widget的框

只容納一個widget,當空間大小不夠的時候,里面的widget可以在主軸上滾動。
你如果需要在兩個方向上收縮包裝(在滾動軸和橫軸)例如 dialog或者 pop-up菜單,在這種情況下,你可以用SingleChildScrollView包裹孩子ListBody

當您有一個子列表并且不需要跨軸收縮包裝行為時,例如,一個始終是屏幕寬度的滾動列表,請考慮ListView,它比包含多個子列表體的ListBody或Column的SingleChildScrollView的效率要高得多。

簡單的代碼:使用一個 ColumnSingleChildScrollView

有時候,布局是圍繞Column的靈活屬性設計的,但是有些時候可能沒有足夠的空間來查看整個內容。這可能是因為一些設備具有異常小的屏幕,或者因為應用程序可以在縱橫比不是最初設想的橫向模式下使用,或者因為應用程序在分割屏幕模式下在小窗口中顯示。無論如何,在singleChildScrollView中包裝布局可能是有意義的。

然而,僅僅這樣做通常會導致Column與SingleChildScrollView之間的沖突,Column通常試圖盡可能地變大,而SingleChildScrollView為子視圖提供了無限大的空間。

為了解決這個明顯的沖突,有一些技術,如下所討論的。這些技術應該只在通常期望內容適合屏幕時才使用,這樣基于sliver的ListView或CustomScrollView的惰性實例化就不會提供任何性能優勢。如果預期視口通常包含超出屏幕尺寸的內容,那么SingleChildScrollView將非常昂貴。

居中、間隔或對齊固定高度的內容

如果內容具有固定的(或內在的)維度,但是需要使用列的Flex布局模型進行分隔、居中或其他定位,那么可以使用以下技術向列提供最小維度,同時允許它在沒有時收縮包裝內容足夠的空間來應用這些間距或對齊需要。

LayoutBuilder用于獲得視口的大小(隱式地通過SingleChildScrollView看到的約束,因為視口通常增長以適應其最大高度約束)。然后,在滾動視圖中,使用ConstrainedBox來設置Column的最小高度。

Column沒有展開的子元素,因此它不是從BoxConstraints.maxHeight獲取無限的高度(viewport不提供最大高度約束),而是自動嘗試收縮以適合其子元素。但是,它不能小于其BoxConstraints.minHeight,因此它變為ConstrainedBox提供的最小高度和子節點高度的總和。

如果子節點不足以適應最小大小,那么Column最終將得到一些剩余空間來分配,這是由Column.mainAxisAlignment參數指定的。

 body: new LayoutBuilder(
          builder: (BuildContext context, BoxConstraints viewportConstraints) {
        return new SingleChildScrollView(
          child: new ConstrainedBox(
            constraints:
                new BoxConstraints(minHeight: viewportConstraints.maxHeight),
            child: new Column(
              mainAxisSize: MainAxisSize.min,
              mainAxisAlignment: MainAxisAlignment.spaceAround,
              children: <Widget>[
                new Container(
                  color: Colors.yellow,
                  height: 120.0,
                ),
                new Container(
                  color: Colors.red,
                  height: 200.0,
                )
              ],
            ),
          ),
        );
      }),

在這個例子中,子結點被平均地間隔開來,除非沒有更多的空間;在沒有更多空間情況下,他們垂直堆疊并滾動。

有足夠空間
空間不足,垂直堆疊

當使用這種技術時,Expanded和Flexible是沒有用的,因為在這兩種情況下,“可用空間”都是無限的(因為這在視口中)。下一節描述了一種提供最大高度約束的技術。

展開內容以適應可視區域

下面的示例建立在前一個示例上。除了為子列提供最小維度之外,還使用IntrinsicHeight小部件強制列與其內容一樣大。這個約束與前面討論的ConstrainedBox約束相結合,以確保該列要么與viewport一樣大,要么與內容一樣大,無論哪個最大。
必須使用這兩個約束來獲得期望的效果。如果只指定了IntrinsicHeight,那么當其子視圖小于整個屏幕時,該列就不會增長到適合整個視圖。如果僅使用視口的大小,則如果兒童大于視口,則列將溢出。

///LayoutBuilder +SingleChildScrollView+IntrinsicHeight+Expanded
      body: new LayoutBuilder(
          builder: (BuildContext cotext, BoxConstraints viewportConstraints) {
        return SingleChildScrollView(
          child: new ConstrainedBox(
            constraints:
                new BoxConstraints(minHeight: viewportConstraints.maxHeight),
            child: new IntrinsicHeight(
              child: new Column(
                children: <Widget>[
                  new Container(
                    color: Colors.yellow,
                    height: 120.0,
                  ),
                  new Expanded(
                      child: new Container(
                    color: Colors.red,
                    height: 50.0,
                  ))
                ],
              ),
            ),
          ),
        );
      }),
image.png

這種技術相當昂貴,因為它或多或少要求對視口的內容進行兩次布局(一次找到它們的內在尺寸,一次實際布局它們)。因此,列中的小部件的數量應該保持較小。或者,具有已知維度的子集可以封裝在具有緊密垂直約束的SiezedBox中,以便當內部大小調整算法到達子樹的那些部分時可以縮短計算。

所以可以看看其他的控件
  • ListVIEW,它處理滾動列表中的多個子項。
  • GRIDVIEW,它處理滾動網格中的多個子類。
  • PageView,一個可滾動的,一頁一頁地工作。
  • Scrollable,處理任意滾動效果。
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,431評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,637評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,555評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,900評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,629評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,976評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,976評論 3 448
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,139評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,686評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,411評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,641評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,129評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,820評論 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,233評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,567評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,362評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,604評論 2 380

推薦閱讀更多精彩內容