flutter 系列之:flutter 中的幽靈offstage

目錄

  • 簡介
  • Offstage詳解
  • Offstage的使用
  • 總結
簡介我們在使用flutter的過程中,有時候需要控制某些組件是否展示 , 一種方法是將這個組件從render tree中刪除,這樣這個組件就相當于沒有出現一樣,但是有時候,我們只是不想展示這個widget,但是這個組件還是存在的,并且可以接受鍵盤輸入,還可以使用CPU 。它和真正的組件唯一不同的就是他是不可見的 。
這樣的組件就叫做Offstage 。今天給大家詳細介紹一下Offstage的使用 。
Offstage詳解我們首先來看下Offstage的定義:
class Offstage extends SingleChildRenderObjectWidget【flutter 系列之:flutter 中的幽靈offstage】可以看到,Offstage是一個包含單個child的Widget 。接下來看下它的構造函數:
const Offstage({ Key? key, this.offstage = true, Widget? child }): assert(offstage != null),super(key: key, child: child);Offstage主要包含兩個屬性,分別是表示是否是offstage狀態的bool值offstage , 如果offstage=true,那么Offstage的子child就會處于隱藏狀態 。這時候子child不會占用任何空間 。
剩下的一個屬性就是child了 。
那么Offstage是如何控制child是否offstage的呢?
我們看下它的createRenderObject方法:
RenderOffstage createRenderObject(BuildContext context) => RenderOffstage(offstage: offstage);可以看到返回的是一個RenderOffstage對象,其中接受一個offstage參數 。
如果深入研究RenderOffstage的話,可以看到他的paint方法是這樣的:
void paint(PaintingContext context, Offset offset) {if (offstage)return;super.paint(context, offset);}如果offstage是true的話,paint方法直接返回,不會進行任何的繪制 。這也就是Offstage的秘密 。
Offstage的使用從上面講解的Offstage的構造函數我們知道,Offstage需要一個bool的offstage屬性 。所以這個offstage屬性是可以變換的,從而觸發offstage的不同狀態 。
因為offstage需要這樣的一個狀態,所以我們在使用offstage的時候,一般來說是創建一個StatefulWidget,從而在StatefulWidget中保持這樣的一個offstage屬性 。
比如我們創建一個OffstageApp,這是一個StatefulWidget,在它的createState方法中,返回一個State<OffstageApp>對象,在createState方法中,我們定義一個_offstage屬性 。
通過使用這個_offstage,我們可以創建Offstage如下:
Offstage(offstage: _offstage,child: SizedBox(key: _key,width: 150.0,height: 150.0,child: Container(color: Colors.red,),),)這里我們設置Offstage的offstage為剛剛設置的_offstage 。
另外為了展示方便,我們將Offstage的child設置為一個SizedBox,里面包含了一個紅色的Container 。
SizedBox包含了width和height屬性,方便我們后續的測試 。
默認情況下,因為_offstage=true,所以這個Offstage是不可見的,那么怎么將其可見呢?
我們提供一個ElevatedButton,在它的onPressed方法中,我們調用setState方法來修改_offstage,如下所示:
ElevatedButton(child: const Text('切換offstage'),onPressed: () {setState(() {_offstage = !_offstage;});},),另外,我們還需要一個ElevatedButton來檢測Offstage的大?。?看看在_offstage發生變化的時候,Offstage到底會不會發生變化 。
ElevatedButton(child: const Text('檢測SizedBox大小'),onPressed: () {ScaffoldMessenger.of(context).showSnackBar(SnackBar(content:Text('SizedBox is ${_getSizedBoxSize()}'),),);})這里的_getSizedBoxSize實現如下:
Size _getSizedBoxSize() {final RenderBox renderBox =_key.currentContext!.findRenderObject()! as RenderBox;return renderBox.size;}我們通過Offstage的_key,來獲取到它的Context,從而找到對應的RenderBox,拿到它的大小 。
好了,這樣我們的代碼就寫好了,最后將OffstageApp放到Scaffold中運行,我們可以得到下面的界面:
flutter 系列之:flutter 中的幽靈offstage

文章插圖
默認Offstage是不會展示的 。
如果我們點擊下面的檢測SizeBox大小的按鈕,可以得到下面的界面:
flutter 系列之:flutter 中的幽靈offstage

文章插圖
可以看到雖然Offstage沒有展示,但是還是獲取到了它的大小 。
然后我們點擊切換Offstage按鈕,可以得到下面的界面:
flutter 系列之:flutter 中的幽靈offstage

文章插圖
界面完美的展示了 。
總結Offstage是一個非常方便的組件,可以用來隱藏我們不需要展示的組件,但是仍然可以獲得它的大小 。

推薦閱讀