基本信息
文件名称:Flutter之可滚动组件实例详解.docx
文件大小:19.62 KB
总页数:7 页
更新时间:2025-06-15
总字数:约5.03千字
文档摘要

Flutter之可滚动组件实例详解

目录正文Scrollable主轴和纵轴ViewportSliver可滚动组件的通用配置ScrollController子节点缓存Scrollbar总结

正文

当内容超过显示视口(ViewPort)时,如果没有特殊处理,Flutter则会提示Overflow错误。为此,Flutter提供了多种可滚动widget(ScrollableWidget)用于显示列表和长布局。

Flutter中有两种布局模型:

基于RenderBox的盒模型布局。基于Sliver(RenderSliver)按需加载列表布局。

通常可滚动组件的子组件可能会非常多、占用的总高度也会非常大;如果要一次性将子组件全部构建出将会非常昂贵!为此,Flutter中提出一个Sliver(中文为薄片的意思)概念,Sliver可以包含一个或多个子组件。Sliver的主要作用是配合:加载子组件并确定每一个子组件的布局和绘制信息,如果Sliver可以包含多个子组件时,通常会实现按需加载模型。

只有当Sliver出现在视口中时才会去构建它,这种模型也称为基于Sliver的列表按需加载模型。可滚动组件中有很多都支持基于Sliver的按需加载模型,如ListView、GridView,但是也有不支持该模型的,如SingleChildScrollView。

Flutter中的可滚动主要由三个角色组成:Scrollable、Viewport和Sliver:

Scrollable:用于处理滑动手势,确定滑动偏移,滑动偏移变化时构建Viewport。Viewport:显示的视窗,即列表的可视区域;Sliver:视窗里显示的元素。

具体布局过程:

Scrollable监听到用户滑动行为后,根据最新的滑动偏移构建Viewport。Viewport将当前视口信息和配置信息通过SliverConstraints传递给Sliver。Sliver中对子组件(RenderBox)按需进行构建和布局,然后确认自身的位置、绘制等信息,保存在geometry中(一个SliverGeometry类型的对象)

比如有一个ListView,大小撑满屏幕,假设它有100个列表项(都是RenderBox)且每个列表项高度相同,结构如下:

图中白色区域为设备屏幕,也是Scrollable、Viewport和Sliver所占用的空间,三者所占用的空间重合,父子关系为:Sliver父组件为Viewport,Viewport的父组件为Scrollable。注意ListView中只有一个Sliver,在Sliver中实现了子组件的按需加载。

其中顶部和底部灰色的区域为cacheExtent,它表示预渲染的高度,需要注意这是在可视区域之外,如果RenderBox进入这个区域内,即使它还未显示在屏幕上,也是要先进行构建的,预渲染是为了后面进入Viewport的时候更丝滑。cacheExtent的默认值是250,在构建可滚动列表时我们可以指定这个值,这个值最终会传给Viewport。

Scrollable

用于处理滑动手势,确定滑动偏移,滑动偏移变化时构建Viewport,我们看一下其关键的属性:

Scrollable({

this.axisDirection=AxisDirection.down,

this.controller,

this.physics,

requiredthis.viewportBuilder,//后面介绍

axisDirection滚动方向。physics:此属性接受一个ScrollPhysics类型的对象,它决定可滚动组件如何响应用户操作,比如用户滑动完抬起手指后,继续执行动画;或者滑动到边界时,如何显示。默认情况下,Flutter会根据具体平台分别使用不同的ScrollPhysics对象,应用不同的显示效果,如当滑动到边界时,继续拖动的话,在iOS上会出现弹性效果,而在Android上会出现微光效果。如果你想在所有平台下使用同一种效果,可以显式指定一个固定的ScrollPhysics,FlutterSDK中包含了两个ScrollPhysics的子类,他们可以直接使用:

AlwaysScrollableScrollPhysics:总是可以滑动

NeverScrollableScrollPhysics:禁止滚动

BouncingScrollPhysics:内容超过一屏上拉有回弹效果

Clampi