簡體   English   中英

Flutter 擴展列表優化、性能和最佳實踐

[英]Flutter Expanding List Optimisation, Performance and Best Practices

在 flutter 中顯示小部件列表的最佳做法是什么,其中可以通過 State 擴展或減少列表的長度。

假設我們有一個 Provider State 來確定長度並相應地呈現小部件。

List _state = Provider.of<Somesuch>(context).routes;

for(int i = 0; i < _state.length; i ++)
Container(child: Text('Item $I'),

測試這個的問題是,如果 state 長度增加,所有的子部件似乎都被重建了。 由於每個實際孩子中包含的動畫數量,這似乎不是最佳方法。

我們嘗試嵌套孩子:

class NestContainer extends StatelessWidget {
  NestContainer({
   this.child = const SizedBox(),
   this.nextChild = const SizedBox(),
});
final Widget child, nextChild;
}

Widget build(BuildContext context) {
  return Stack(children:[
    child,
    nextChild,
  ]);
}

然后作為一些 Widget 的孩子:

Builder(builder: (context) {
  List _state = Provider.of<Somesuch>(context).routes;

  buildContainer(int index){
    return NestContainer(
      child: Container(child: Text('Item $index')),
      nextChild

: _state.asMap().containsKey(index + 1) ?
    buildContainer(index + 1) : const SizedBox()
    
    }
return buildContainer(0);
});

這似乎不會導致重建,但我擔心函數的使用,因為文檔中不鼓勵這樣做。

它還使得將實際內容傳遞給這些孩子,以便在技術上更多地涉及所有潛在的孩子(實際上是地圖中包含的頁面路由)。 每個 NestContainer 都需要接收整個 Map 以便它可以從中呈現正確的項目,這意味着將大量未使用的數據傳遞給每個 NestContainer。

處理這個問題的最佳方法是什么?

鑰匙很重要。 它們允許 flutter 將一堆小部件作為一個整體來查看,並確定該堆棧中的任何內容是否發生了變化。

List _state = Provider.of<Somesuch>(context).routes;

for(int i = 0; i < _state.length; i ++)
Container(key: ValueKey('Container $I'), child: Text('Item $I'),

添加該鍵意味着如果該容器沒有更改並且它在列表中的位置沒有更改,則不會檢查任何更改。

但是,這不是完整的答案。 Memory 的使用基於屏幕上呈現的一些小部件等。 擺脫屏幕上沒有的任何東西很重要。

許多人會說最好的方法是從樹中刪除未使用的小部件。 IE

Stack(children:[
someStatefield ? SomeWidget() : SizedBox()
])

這是事實,但並不總是可行,尤其是在復雜的導航器中。 這個想法是用盡可能少的內容替換屏幕上看不到的小部件,直到需要再次看到它們為止。

最簡單的方法是使用 Visibility class。使用Visibility(visible: false)時,此 class 的子級將被替換為 SizedBox,並且在設置為 true 時恢復其內容。 添加maintainState: true將允許它保持對任何其他 state 更改的響應,而無需呈現任何內容或執行任何動畫,直到它再次可見。

Visibility(
  visible: (true or false based on your state),
  maintainState: true // ensures the child still responds to changes in state despite rendering no content or animations
  child: // Your Widgets and content that will be replaced by a SizedBox when not visible
)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM