英文地址:Flutter ListView and ScrollPhysics: A Detailed Look
探究ListView的类型
我们将先查看listview的类型,然后查看它的其他特性和整洁性修改。
列表视图的类型:
- ListView
- ListView.builder
- ListView.separated
- ListView.custom
ListView
这个是ListView类的默认构造函数,仅仅接收children列表就能够实现滚动效果。
代码一般格式如下:
1 | ListView( |
通常,这适用于少量子组件的使用,因为列表也将会构建不可见的元素,而渲染大量的元素会影响性能效率。
ListView.builder()
这个builder()
构造函数来构造重复性的列表项,这个构造函数有两个主要的参数:itemCount(列表项个数),itemBuilder用于构建具体每个列表项目。
代码一般格式如下:
1 | ListView.builder( |
这些列表项是惰性构造的,意味着只会构造特定数量的列表项,当用户向前滚动时,之前的列表项就会被销毁。
(巧妙的技巧)Neat trick:因为这些元素是惰性载入的,仅有被需要数量的元素被载入进去。我们可以不必需要itemCount
作为一个强制参数,这样列表将会是无限的。
1 | ListView.builder( |
ListView.separated()
在separated()
构造函数中,我将会生成一个列表,并且我们可以指定列表项之间的分隔符。
本质上,我们构造了两个交织的列表,一个作为主列表,另一个作为分割列表。
注意,上面的构造函数谈及的无限数量的列表项不能在这里使用,这个构造函数强制需要一个itemCount
参数。
代码的一般格式如下:
1 | ListView.separated( |
这种类型的列表允许你动态构造分割符,不同类型的列表项,可拥有不同的分隔符,按需添加/移除分割符等等。
此实现可以轻松插入其他类型的元素(例如:广告),而无需修改这些列表项中间的主列表。
注意:分隔符列表长度比这些列表项少1个,因为在最后一个元素之后不存在分隔符。
ListView.custom()
这个custom()
构造函数如其名,允许你使用定义功能(这些列表中的子组件是如何构建的)来构建ListView
。为此,所必须的主要参数是一个SliverChildDelegate
,用于构建这些列表项目。
SliverChildDelegate
的类型如下:
- SliverChildListDelegate
- SliverChildBuilderDelegate
SliverChildListDelegate
直接接收一个children
列表,而SliverChildBuilderDelegate
接收一个IndexedWidgetBuilder
(我们使用的builder
函数)。
您可以使用或继承它们来构建自己的委托。
ListView.builder本质上是ListView.custom使用一个SilverChildBuilderDelegate。
ListView默认构造函数的行为类似于ListView.custom使用一个SliverChildListDelegate。
探究滚动原理
为了控制滚动的发生方式,我们在ListView
构造函数设置physics
参数,类型如下:
NeverScrollablePhysics
使用这个,将会完全禁用滚动。
BouncingScrollPhysics
在列表结束的时候会有一个反弹效果,iOS上也是使用了类似的效果。
ClampingScrollPhysics
这是Android上使用的默认scrolling physics。列表在末尾停止,并给出一个指示它的效果。
FixedExtentScrollPhysics
这个稍微与其他的不同,这个仅对FixedExtendScrollControllers
和使用它们的列表有效。例如,我们将以ListWheelScrollView
为例,它生成一个具有滚轮效果的列表。
FixedExtentScrollPhysics
只会滚动到项,而不会是其之间的任何偏移量。
这个例子的代码非常简单:
1 | FixedExtentScrollController fixedExtentScrollController = |
更多
如何使列表中被销毁的元素保持活动状态?
Flutter提供了一个KeepAlive()
小部件,该小部件使一个本来会被销毁的项保持活跃状态。在列表中,元素默认被包装在AutomaticKeepAlive
小部件中。
可以通过将addAutomaticKeepAlives
字段设置为false
来禁用AutomaticKeepAlives
。这在不需要保持元素活跃或自定义KeepAlive
实现的情况下非常有用。
为什么我的列表视图在列表和外部小部件之间存在空隙??
默认情况下,ListView与外部小部件之间有填充,要移除它,将填充设置为EdgeInset.all(0.0)
。