Flutter-詳解布局(彈性和層疊布局輔助控件)

DEMO

彈性布局輔助控件

1. Expanded

  • 說(shuō)明: 作為Row、Column或Flex的子Widget,可以擴(kuò)展以填充主軸上的可用空間

  • 規(guī)則: 必須位于Row、Column或Flex內(nèi)。flex參數(shù)用于分配剩余空間的比例(默認(rèn)為1)

  • 注意: 在Row或Column中,如果子Widget的總主軸長(zhǎng)度超過(guò)可用空間,使用Expanded可以避免溢出,因?yàn)樗鼤?huì)壓縮子Widget(強(qiáng)制子Widget適應(yīng)分配的空間)

  • 推薦: 在需要子Widget按比例分配空間時(shí)使用,比例分割布局(如 70%-30% 面板)

Row(
  children: [
    Expanded(flex: 2, child: Container(color: Colors.red)), // 占2/3空間
    Expanded(flex: 1, child: Container(color: Colors.green)), // 占1/3空間
  ],
)
Expanded

2. Flexible

  • 說(shuō)明: 與Expanded類(lèi)似,但更靈活。Expanded是Flexible(fit: FlexFit.tight)的簡(jiǎn)寫(xiě)。Flexible的默認(rèn)fit是FlexFit.loose,即子Widget不需要填滿分配的空間

  • 規(guī)則: 同樣必須位于Row、Column或Flex內(nèi)

  • 注意: Flexible與Expanded的區(qū)別:Expanded會(huì)強(qiáng)制子Widget填滿空間,而Flexible則允許子Widget使用更小的空間

  • 推薦: 當(dāng)需要子Widget有彈性但不需要強(qiáng)制填滿時(shí)使用,自適應(yīng)表格列

Row(
    children: [
      Flexible(
        child: Container(height: 50, color: Colors.red),
      ),
      
      Flexible(
        child: Container(
            height: 100,
            color: Colors
                .green), // 這個(gè)容器高度100,但Row高度由最高子Widget決定(100),紅色容器高度50,但會(huì)被拉伸到100(因?yàn)镽ow交叉軸是垂直方向,默認(rèn)是stretch)
      ),
    ],
)

注意:Row的交叉軸對(duì)齊默認(rèn)是stretch,所以子Widget在垂直方向會(huì)被拉伸。如果不想被拉伸,可以設(shè)置crossAxisAlignment: CrossAxisAlignment.start。

Flexible

3. Spacer

  • 說(shuō)明: 在彈性布局中占據(jù)剩余空間(相當(dāng)于Expanded包裹一個(gè)空的SizedBox),是一個(gè)用于在 Row、Column 或 Flex 布局中填充剩余空間的空白組件

  • 規(guī)則: 它會(huì)根據(jù) flex 參數(shù)按比例占據(jù)主軸(水平或垂直方向)的可用空間,類(lèi)似彈性布局中的“彈簧”,flex(默認(rèn)值為1):指定空間分配比例。例如,兩個(gè) Spacer(flex: 2) 和 Spacer(flex: 1) 會(huì)按 2:1 分配剩余空間

  • 注意: 必須作為 Row、Column 或 Flex 的直接子組件,空間不足時(shí)可能引發(fā)溢出錯(cuò)誤(需確保父容器有足夠空間)

  • 推薦: 等間距按鈕組,左右對(duì)齊元素,多比例空間分配

Column(
  children: [
    const Text(
      "頂部標(biāo)題",
      style: TextStyle(
        color: Colors.blue,
      ),
    ),
    const Spacer(flex: 1),
    const Row(
      children: [
        Text(
          "左側(cè)文本",
          style: TextStyle(
            color: Colors.black,
          ),
        ),
        Spacer(flex: 2),
        Text("中間文本",
            style: TextStyle(
              color: Colors.red,
            )),
        Spacer(flex: 1),
        Icon(Icons.star),
      ],
    ),
    const Spacer(flex: 3), // 下方大面積留白
    ElevatedButton(
      onPressed: () {},
      child: const Text(
        "確認(rèn)",
        style: TextStyle(
          color: Colors.blue,
        ),
      ),
    ),
  ],
)
Spacer

層疊布局輔助控件

1. Positioned

  • 說(shuō)明: 僅作為 Stack 的直接子組件使用,用于在層疊布局中精確定位子組件,類(lèi)似 CSS 的絕對(duì)定位

  • 規(guī)則: left、right、top、bottom(控制子組件相對(duì)于父 Stack 邊緣的距離),width、height(可選,用于固定子組件尺寸),支持 Positioned(topLeft/bottomRight) 等快捷方式

  • 注意: 若設(shè)置 left + right,則不能同時(shí)設(shè)置 width;同理適用于 top + bottom 與 height 的沖突,未設(shè)置尺寸時(shí),需至少指定兩個(gè)相對(duì)定位屬性(如 left 和 right)以確定布局范圍

  • 推薦: 結(jié)合 MediaQuery 動(dòng)態(tài)計(jì)算定位值,適配不同屏幕尺寸,使用 Align 簡(jiǎn)化對(duì)齊邏輯

Stack(
  fit: StackFit.expand, // 填充父容器
  children: [
    Positioned(
      left: 10,
      right: 10,
      height: 80,
      child: Container(color: Colors.orange), // 水平居中且寬度自適應(yīng)
    ),
    Positioned(
      top: 10,
      bottom: 10,
      width: 80,
      child: Container(color: Colors.purple), // 垂直居中且高度自適應(yīng)
    ),
  ],
)
Positioned

2. PositionedDirectional

  • 說(shuō)明: 它用于在 Stack 中根據(jù) textDirection 的方向來(lái)定位子部件。與 Positioned 不同,PositionedDirectional 接受的是一個(gè)偏移量和一個(gè) textDirection 參數(shù),從而決定子部件相對(duì) Stack 的位置。這使得在布局中使用 PositionedDirectional 更加靈活和方便

  • 規(guī)則: start:在 TextDirection.ltr (從左到右)時(shí)對(duì)應(yīng) left,在 TextDirection.rtl (從右到左)時(shí)對(duì)應(yīng) right。end:在 TextDirection.ltr 時(shí)對(duì)應(yīng) right,在 TextDirection.rtl 時(shí)對(duì)應(yīng) left。top 和 bottom 保持固定方向,不受文本方向影響

  • 注意: 必須作為 Stack 的直接子組件,否則會(huì)拋出錯(cuò)誤,支持 width 和 height 屬性,但需注意與 start/end 和 top/bottom 的組合規(guī)則

  • 推薦: 可通過(guò) AnimatedPositionedDirectional 實(shí)現(xiàn)位置變化的動(dòng)畫(huà)效果,適配不同語(yǔ)言方向的布局(如阿拉伯語(yǔ)、希伯來(lái)語(yǔ))

Directionality(
  // 設(shè)置文本方向(ltr 或 rtl)
  textDirection: TextDirection.rtl,
  child: Stack(
    children: [
      PositionedDirectional(
        start: 20.0, // 在 rtl 環(huán)境下對(duì)應(yīng) right=20
        top: 50.0,
        child: Container(
          width: 100,
          height: 100,
          color: Colors.blue,
          child: const Center(child: Text('動(dòng)態(tài)定位')),
        ),
      ),
      // 其他子組件...
    ],
  ),
)
PositionedDirectional

因?yàn)榫W(wǎng)站字?jǐn)?shù)限制,只能分系列了,需要一次性看完請(qǐng)去這里
Flutter-詳解布局(核心布局控件)
Flutter-詳解布局(單子組件布局控件)
Flutter-詳解布局(滾動(dòng)和Sliver系列布局控件)
Flutter-詳解布局(響應(yīng)式和平臺(tái)適配及特殊布局控件)
需要代碼去這里DEMO

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容