返回

ListView复用:哥布林也能分分钟实现?实验性想法和发现

Android

前言

这篇文章是对最近 Flutter 中 ListView 研究的总结。一直以来,我对 Flutter 的设计都不太感兴趣,尤其是在完成那个支持仿真翻页的小说阅读器的时候。我经常想:一个声称以性能为傲的框架,为什么在实现一个如此基本的功能(列表视图)时如此复杂?

问题

在 Flutter 中,ListView 的复用性一直是一个问题。当列表项数量较多时,频繁创建和销毁 widget 会导致性能问题。为了解决这个问题,Flutter 提供了几个内置解决方案,例如 SliverListIndexedListView。然而,这些解决方案要么功能受限,要么不够灵活。

实验

为了探索 ListView 复用的替代方法,我进行了一些实验。我的目标是创建一个高性能、高度可定制的 ListView,它可以处理大数据集。

第一个实验是使用 CustomScrollViewSliverFillViewport 来模拟 ListView 的行为。通过这种方式,我可以手动控制列表项的创建和销毁。这个方法非常有效,但是实现起来很复杂,而且不适用于所有场景。

第二个实验是使用 RenderObject 来直接操作 Flutter 的渲染管道。这个方法给了我完全的控制权,但是它需要对 Flutter 的内部工作原理有深入的了解。而且,它违反了 Flutter 的封装原则,可能会导致意外后果。

发现

通过这些实验,我得出了一些关于 ListView 复用的重要发现:

  • 手动管理 widget 生命周期是至关重要的。 通过手动控制 widget 的创建和销毁,可以显著提高性能。
  • Flutter 的渲染管道非常强大。 通过直接操作 RenderObject,可以实现高度可定制的解决方案。
  • 违反 Flutter 的封装原则需要谨慎。 虽然它可以提供灵活性,但它也可能导致意外后果。

解决方法

基于这些发现,我提出了一种新的 ListView 复用解决方案,称为 ReusableListView。该解决方案结合了手动管理 widget 生命周期和直接操作渲染管道。它既高效又灵活,适用于各种场景。

实现

ReusableListView 的实现相对简单。它使用 CustomScrollViewSliverFillViewport 作为基础,并通过一个自定义 RenderObject 来管理 widget 生命周期。这个 RenderObject 跟踪列表项的可见性,并在必要时创建或销毁它们。

性能

为了评估 ReusableListView 的性能,我进行了一系列基准测试。结果表明,ReusableListView 在处理大数据集时比 Flutter 的内置解决方案快得多。

限制

尽管 ReusableListView 性能优异,但它也有几个限制:

  • 它不适用于所有场景,例如具有复杂布局的列表项。
  • 它需要对 Flutter 的内部工作原理有基本的了解。

结论

虽然 Flutter 的内置 ListView 复用解决方案已经很不错了,但我相信 ReusableListView 提供了更高级别的性能和灵活性。通过手动管理 widget 生命周期和直接操作渲染管道,ReusableListView 可以显着提高列表视图的大数据集处理性能。