天天看點

flutter系列之:按比例縮放的AspectRatio和FractionallySizedBox

目錄

  • ​​簡介​​
  • ​​AspectRatio​​
  • ​​FractionallySizedBox​​
  • ​​總結​​

簡介

我們在建構UI的時候,為了适應不同的螢幕大小,通常需要進行一些自适應的配置,而最常見的自适應就是根據某個寬度或者高度自動進行元件的縮放。

今天要給大家介紹兩個可以自動縮放的元件AspectRatio和FractionallySizedBox。

AspectRatio

AspectRatio的目的就是将其child按比例縮放。

先來看下AspectRatio的定義:

class AspectRatio extends SingleChildRenderObjectWidget      

可以看到AspectRatio繼承自SingleChildRenderObjectWidget,表示用來呈現一個single child。

AspectRatio需要的屬性有兩個,分别是aspectRatio和子元素child。

aspectRatio是一個double類型的資料,為了友善起見,我們一般使用比例的格式來進行表示,比如3.0/2.0等。

雖然我們知道3/2的結果是1.5,但是我們最好不要自行計算結果,因為使用3.0/2.0更加直覺。

AspectRatio的邏輯是首先獲得最大的width或者height,然後根據width或者height來計算height和width。接下來我們來看幾個具體的例子,來詳細了解AspectRatio。

首先是一個無限寬度但是高度為150的container,然後再container的child中使用了AspectRatio元件,如下所示:

Widget build(BuildContext context) {
    return Container(
      color: Colors.blue,
      alignment: Alignment.center,
      width: double.infinity,
      height: 150.0,
      child: AspectRatio(
        aspectRatio: 3 / 2,
        child: Container(
          color: Colors.red,
        ),
      ),
    );      

這裡的aspectRatio=3/2, 那麼怎麼來計算aspectRatio的大小呢?

對于aspectRatio的父widget來說,他的寬度是無限的,他的高度是150,是以aspectRatio的高度是可以确定的,也就是150,我們根據aspectRatio的比例,計算出它的width=150/2 * 3 = 225, 如下所示:

flutter系列之:按比例縮放的AspectRatio和FractionallySizedBox

再看下面的一個例子:

Widget build(BuildContext context) {
    return Container(
      color: Colors.blue,
      alignment: Alignment.center,
      width: 150.0,
      height: 150.0,
      child: AspectRatio(
        aspectRatio: 2.0,
        child: Container(
          color: Colors.red,
        ),
      ),
    );
  }      

這個例子中Container的width和height是相等的。

在它的child中使用的aspectRatio=2.0。如果child的height選擇=150,那麼對應的width就應該是300,很明顯超出了Container的範圍,是以這裡選擇的是width=150, 而對應的height=75, 入下圖所示:

flutter系列之:按比例縮放的AspectRatio和FractionallySizedBox

那麼問題來了, 如果AspectRatio指定了大小應該怎麼處理呢?

比如我們給aspectRatio的child添加一個width和height限制:

Widget build(BuildContext context) {
    return Container(
      color: Colors.blue,
      alignment: Alignment.center,
      width: 150.0,
      height: 150.0,
      child: AspectRatio(
        aspectRatio: 2.0,
        child: Container(
          color: Colors.red,
          width: 50,
          height: 50,
        ),
      ),
    );
  }      

你會發現這個width和height對Container的大小是沒有效果的。

這裡就要談到之前我們提到的constraints了,對于AspectRatio來說,他希望子child填充滿它的空間,是以child會繼承這個constraints,進而展示相同的界面。

FractionallySizedBox

FractionallySizedBox和AspectRatio有些類似,不過FractionallySizedBox是按照可用空間的大小來進行比例設定的。

首先來看下FractionallySizedBox的定義:

class FractionallySizedBox extends SingleChildRenderObjectWidget      

可以看到FractionallySizedBox和AspectRatio一樣繼承自SingleChildRenderObjectWidget。

FractionallySizedBox有三個屬性,分别是alignment,widthFactor和heightFactor。

其中alignment表示的是FractionallySizedBox中子child的排列方式。

而widthFactor和heightFactor是double類型的,表示的是對應的縮放比例。

接下來,我們看一下FractionallySizedBox的具體使用。

Widget build(BuildContext context) {

    return FractionallySizedBox(
      widthFactor: 1,
      heightFactor: 0.25,
      alignment: FractionalOffset.center,
      child: DecoratedBox(
        decoration: BoxDecoration(
          border: Border.all(
            color: Colors.red,
            width: 4,
          ),
        ),
      ),
    );
  }      

這裡我們設定對應的widthFactor=1和heightFactor=0.25, 也就是說widht和可用空間的width是一緻的,而height隻有原來的1/4。

為了友善起見,我們将child用一個DecoratedBox封裝起來,用來展示box的邊界,最後得到的界面如下所示:

flutter系列之:按比例縮放的AspectRatio和FractionallySizedBox

總結

熟練使用AspectRatio和FractionallySizedBox可以很友善的按比例來繪制界面的元素,非常好用。

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

更多内容請參考 ​​www.flydean.com​​

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