动态

详情 返回 返回

【Flutter 2-9】Flutter手把手教程UI佈局和Widget——彈性佈局控件Flexible - 动态 详情

作者 | 弗拉德
來源 | 弗拉德(公眾號:fulade_me)

Flexible

Flexible可以幫助Row、Column、Flex的子控件充滿父控件,它的用法很靈活,也具有權重的屬性。跟Flexible相類似的控件還有Expanded。
先來看Flexible的構造函數

const Flexible({
    /// key
    Key key,
    // 默認 flex 的值為 1
    this.flex = 1,
    /// 默認 fit參數為 FlexFit.loose 表示子控件可以以最小的大小來佈局
    this.fit = FlexFit.loose,
    @required Widget child,
}) 

按比例佈局

Flexible的參數flex是表示比例的值。
假如我們在Column內部有三個子控件,每個控件的flex值都設置為1
那麼這三個子控件的高度都是Column高度(Row的情況下就是寬度)的三分之一,也就是三個子控件均分了Column的高度(Row的情況下就是寬度)

Column(
    crossAxisAlignment: CrossAxisAlignment.center,
    children: [
        Flexible(
            child: Image.asset("images/image_demo.jpg"),
            flex: 1,
        ),
        Flexible(
            child: Image.asset("images/image_demo.jpg"),
            flex: 1,
        ),
        Flexible(
            child: Image.asset("images/image_demo.jpg"),
            flex: 1,
        ),
    ],
)

如下圖:
2020_01_14_flexible_1_1_1

然後我們把flex的值分別設置為123,那麼這個三個控件的高度分別是五分之一、五分之二、五分之三的高度

Column(
    crossAxisAlignment: CrossAxisAlignment.center,
    children: [
        Flexible(
            child: Image.asset("images/image_demo.jpg"),
            flex: 1,
        ),
        Flexible(
            child: Image.asset("images/image_demo.jpg"),
            flex: 2,
        ),
        Flexible(
            child: Image.asset("images/image_demo.jpg"),
            flex: 3,
        ),
    ],
)

效果如下圖:
2020_01_14_flexible_1_2_3

FlexFit.loose 和 FlexFit.tight

枚舉值 描述
loose loose表示允許以最小的高度(Row下是寬度)佈局 可以忽略flex的值
tight 必須以設置的最大的flex值來顯示
Column(
    crossAxisAlignment: CrossAxisAlignment.center,
    children: [
        Flexible(
            child: Image.asset("images/image_demo.jpg"),
            flex: 1,
        ),
        Flexible(
            child: Image.asset(
            "images/image_demo.jpg",
            height: 80,
            ),
            fit: FlexFit.loose,
            flex: 2,
        ),
        Flexible(
            child: Image.asset("images/image_demo.jpg"),
            flex: 2,
        ),
    ],
)

我們給第二個控件設置的flex值為2,給Image設置的高度為80,給fit的值設置為FlexFit.loose,這個時候優先起到作用的是FlexFit.looseflex的值會被忽略,所以這裏的Image會以高度為80的大小來顯示。
效果如下圖:
2020_01_14_flexible_loose

Column(
    crossAxisAlignment: CrossAxisAlignment.center,
    children: [
        Flexible(
            child: Image.asset("images/image_demo.jpg"),
            flex: 1,
        ),
        Flexible(
            child: Image.asset(
            "images/image_demo.jpg",
            height: 80,
            ),
            fit: FlexFit.tight,
            flex: 2,
        ),
        Flexible(
            child: Image.asset("images/image_demo.jpg"),
            flex: 2,
        ),
    ],
)

我們把FlexFit.loose改為FlexFit.tight,此時就會忽略當前設置的高度80,直接使用比例來顯示。
效果如下圖:
2020_01_14_flexible_tight

優先佈局

如果我們將flex的值設置為0,此時Flexible並不是被分配0的高度,而是flex值為0的Flexible會優先佈局且會盡量大的佔用Column的高度

Column(
    children: [
        Flexible(
            child: Image.asset("images/image_demo.jpg"),
            flex: 1,
        ),
        Flexible(
            child: Image.asset("images/image_demo.jpg"),
            flex: 2,
        ),
        Flexible(
            child: Image.asset("images/image_demo.jpg"),
            flex: 0,
        ),
    ],
)

2020_01_14_flexible_flex_00
可以看到第三個Flexible是高度最大的,因為它優先佔用最高的高度。

填充剩餘的空間

很多情況下在Column內不止是有Flexible控件,還有像Container這種控件。在二者都存在的情況下,Container會優先佈局並佔用自己需要的高度,剩餘的高度由Flexible控件來填充滿。如果有多個Flexible控件,它們會按自己設置的flex值來均分剩餘的高度。

Column(
    children: [
        Container(
            child: Image.asset("images/image_demo.jpg"),
            width: 100,
            height: 100,
        ),
        Container(
            child: Image.asset("images/image_demo.jpg"),
            width: 100,
            height: 100,
        ),
        Flexible(
            child: Container(
                decoration: BoxDecoration(color: Colors.green),
                width: 300,
            ),
        ),
    ],
)

效果如下:
2020_01_14_flexible_flex_space_full

想體驗以上示例的運行效果,可以到我的Github倉庫項目flutter_app->lib->routes->flexible_page.dart查看,並且可以下載下來運行並體驗。


公眾號

user avatar u_17037082 头像 u_14540126 头像 ireashare 头像 flutterdev 头像 qishiwohendou 头像 ligaai 头像 eolink 头像 vivotech 头像 haoqidedalianmao 头像 zhoumo_62382eba4b454 头像 wodekouwei 头像 cbuc 头像
点赞 35 用户, 点赞了这篇动态!
点赞

Add a new 评论

Some HTML is okay.