繁体   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