flutter系列之:把box佈局用出花來

2022-10-14 15:02:36

簡介

flutter中的layout有很多,基本上看layout的名字就知道這個layout到底是做什麼用的。比如說這些layout中的Box,從名字就知道這是一個box的佈局,不過flutter中的box還有很多種,今天我們來介紹最常用的LimitedBox,SizedBox和FittedBox。

LimitedBox

LimitedBox是一種限制大小的Box,先來看下LimitedBox的定義:

class LimitedBox extends SingleChildRenderObjectWidget 

可以看到LimitedBox繼承自SingleChildRenderObjectWidget,表示LimitedBox中可以有一個single child。

那麼LimitedBox一般用在什麼地方呢?

考慮在一個可捲動列表的情況下,比如ListView,因為他是unbounded的,如果ListView的子widget是Container的話,Container會盡可能的小,這很明顯不是我們所想要的,我們以下面的程式碼為例:

  Widget build(BuildContext context) {
    return ListView(
      children: [
        for(var i=0; i < 10 ; i++)
          Container(
            color: list[i % 4],
          )
      ],
    );
  }

在ListView中,我們新增了一個Container,這些Container中只設定了color,並且並未設定任何大小,那麼將會得到下面的介面:

可以看到現在看到的介面是空白的。

當然,你可以給Container設定height屬性來達到對應的目的:

  Widget build(BuildContext context) {
    return ListView(
      children: [
        for(var i=0; i < 10 ; i++)
          Container(
            height: 100,
            color: list[i % 4],
          )
      ],
    );
  }

或者使用LimitedBox來達到同樣的效果:

  Widget build(BuildContext context) {
    return ListView(
      children: [
        for(var i=0; i < 10 ; i++)
          LimitedBox(
            maxHeight: 100,
            child: Container(
              // height: 100,
              color: list[i % 4],
            ),
          )
      ],
    );
  }

我們可以得到下面的介面:

SizedBox

SizedBox從名字就知道是給box一個指定的size。

先來看下Sizedbox的定義:

class SizedBox extends SingleChildRenderObjectWidget

可以看到SizedBox繼承自SingleChildRenderObjectWidget,表示它可以包含一個child widget。

然後再來看下它的建構函式:

const SizedBox({ Key? key, this.width, this.height, Widget? child })

SizedBox主要接受width,height和它的child widget。SizedBox主要用來強制它的child widget的width和height保持一致。

我們來看一個具體的例子:

  Widget build(BuildContext context) {
    return SizedBox(
      width: 200.0,
      height: 200.0,
      child: Container(
        color: Colors.blue,
      ),
    );
  }

上面的例子中我們指定了固定SizedBox。最後得到的介面如下:

事實上SizedBox的width和height並不一定是固定的值,我們可以將他們設定為double.infinity,表示child widget會盡可能的填充。

比如下面的例子:

  Widget build(BuildContext context) {
    return SizedBox(
      width: double.infinity,
      height: double.infinity,
      child: Container(
        color: Colors.blue,
      ),
    );
  }

展示的介面是這樣的:

SizedBox也提供了一個expand方法來提供類似的功能:

  Widget build(BuildContext context) {
    return SizedBox.expand(
      child: Container(
        color: Colors.blue,
      ),
    );
  }

上面的程式碼和使用double.infinity是等價的。

SizedBox還可以不包含任何child,在這種情況下,SizedBox表示的就是一個空白gap。

FittedBox

FittedBox就是填充box的意思,可以按照指定的fit規則來填充它的child。

先來看下FittedBox的定義:

class FittedBox extends SingleChildRenderObjectWidget {

FittedBox繼承自SingleChildRenderObjectWidget,表示它也只包含一個child。

再看下FittedBox的建構函式:

  const FittedBox({
    Key? key,
    this.fit = BoxFit.contain,
    this.alignment = Alignment.center,
    this.clipBehavior = Clip.none,
    Widget? child,
  })

FittedBox有幾個非常有意思的引數,首先是fit,表示如何填充Box,它是一個BoxFit物件,BoxFit有幾個值,用來描述fix的方式。

比如fill表示填充到box中,不管之前child的長寬比,而contain表示的是儘可能的包含child。

alignment是一個AlignmentGeometry,表示的是child的排列方式。

clipBehavior表示的是Box和child重疊的時候的剪下方式。

我們看一個具體的例子:

  Widget build(BuildContext context) {
    return FittedBox(
      fit: BoxFit.fill,
      child: Image.asset('images/head.jpg'),
    );
  }

上面例子中,我們使用了BoxFit.fill來填充,我們看下具體的效果:

總結

這幾個box是我們在日常的工作中經常會用到的box。大家可以熟練掌握。

本文的例子:https://github.com/ddean2009/learn-flutter.git

更多內容請參考 https://www.cnblogs.com/flydean/p/www.flydean.com

最通俗的解讀,最深刻的乾貨,最簡潔的教學,眾多你不知道的小技巧等你來發現!

歡迎關注我的公眾號:「程式那些事」,懂技術,更懂你!