深入Flutter(四) Infinite scrolling -- 无限滚动

文章系列
深入Flutter(一) 积极推进“组合”方式
深入Flutter(二) 线性时间复杂度的 build 和 layout
深入Flutter(三) Element树和RenderObject树
深入Flutter(五) 专业化API

原文:Inside Flutter

译者额外添加flutter的渲染流程图,有助于理解本文:
图一、
在这里插入图片描述
图二、
在这里插入图片描述

Infinite scrolling – 无限滚动

Infinite scrolling lists are notoriously difficult for toolkits. Flutter supports infinite scrolling lists with a simple interface based on the builder pattern, in which a ListView uses a callback to build widgets on demand as they become visible to the user during scrolling. Supporting this feature requires viewport-aware layout and building widgets on demand.
众所周知,无限滚动列表对于工具包来说非常困难。 Flutter通过基于builder设计模式的简单interface支持无限滚动列表,其中** ListView **使用callback按需build widget,因为在滚动过程中用户可以看到它们。 支持此功能需要视口感知的layout和按需build widget。

Viewport-aware layout – 视口感知(Viewport-aware) layout

Like most things in Flutter, scrollable widgets are built using composition. The outside of a scrollable widget is a Viewport, which is a box that is “bigger on the inside,” meaning its children can extend beyond the bounds of the viewport and can be scrolled into view. However, rather than having RenderBox children, a viewport has RenderSliver children, known as slivers, which have a viewport-aware layout protocol.
像Flutter中的大多数东西一样,可滚动widget是使用组合进行build的。 可滚动widget的外部是“Viewport”(可见区域),这是一个“内部较大”的框,这意味着其子项可以扩展到“Viewport”(可见区域)的范围之外并可以滚动到视图中。 但是,Viewport并非是持有RenderBox的实现子类,而是具有RenderSliver子类(称为Sliver),它们具有视口感知(viewport-aware)的layout协议。

The sliver layout protocol matches the structure of the box layout protocol in that parents pass constraints down to their children and receive geometry in return. However, the constraint and geometry data differs between the two protocols. In the sliver protocol, children are given information about the viewport, including the amount of visible space remaining. The geometry data they return enables a variety of scroll-linked effects, including collapsible headers and parallax.
sliver layout 协议与box layout协议的结构相对比,因为父级将constraint下传给子级,并接收几何信息(大小等)作为return。 但是,两种协议之间的constraint和几何数据不同。 在sliver协议中,将为子级提供有关viewport(可见区域)的信息,包括剩余的可见空间量。 它们return的几何数据可实现各种滚动链接效果,包括可折叠的标题和视差(parallax)

Different slivers fill the space available in the viewport in different ways. For example, a sliver that produces a linear list of children lays out each child in order until the sliver either runs out of children or runs out of space. Similarly, a sliver that produces a two-dimensional grid of children fills only the portion of its grid that is visible. Because they are aware of how much space is visible, slivers can produce a finite number of children even if they have the potential to produce an unbounded number of children.
不同的sliver以不同的方式填充viewport中的可用空间。 例如,一条产生线性(linear)子项列表的sliver按顺序排列每个子项,直到sliver用完子项或空间用完为止。 类似地,产生二维子网格(grid)的sliver仅填充网格(grid)的可见部分。 因为他们知道有多少空间可见,所以sliver可以仅产生有限数量的子代,即使它们有可能需要产生无限的子代(译者:意思是仅仅生成需要展示的部分)。

Slivers can be composed to create bespoke scrollable layouts and effects. For example, a single viewport can have a collapsible header followed by a linear list and then a grid. All three slivers will cooperate through the sliver layout protocol to produce only those children that are actually visible through the viewport, regardless of whether those children belong to the header, the list, or the grid.
Slivers 可以通过组合的方式实现定制的滚动layout和效果。 例如,单个viewport可以同时具有可折叠的标题(header),然后是线性(linear)列表,再然后是网格(grid)。 总共三个sliver将通过sliver layout 协议(protocol)进行协作,以此,仅仅生成那些在viewport中实际可见的子项,而不管这些子项是属于标题(header),列表(linear)还是网格(grid)。

Building widgets on demand --按需build widget

If Flutter had a strict build-then-layout-then-paint pipeline, the foregoing would be insufficient to implement an infinite scrolling list because the information about how much space is visible through the viewport is available only during the layout phase. Without additional machinery, the layout phase is too late to build the widgets necessary to fill the space. Flutter solves this problem by interleaving the build and layout phases of the pipeline. At any point in the layout phase, the framework can start building new widgets on demand as long as those widgets are descendants of the render object currently performing layout.
如果Flutter具有严格的 build -> layout -> paint 管道(pipeline),则前述内容将不足以实现无限滚动列表,因为有关通过viewport可见的空间量的信息仅在layout段才可用。 如果没有其他机制,layout阶段就太晚了,无法build填充空间所需的widgets。 Flutter通过交错管道pipelinebuild和layout阶段来解决此问题。 在layout阶段的任何时候,只要这些widget是当前正在执行layout的渲染对象的子类,framework都可以根据需要开始构建新的widget。

Interleaving build and layout is possible only because of the strict controls on information propagation in the build and layout algorithms. Specifically, during the build phase, information can propagate only down the tree. When a render object is performing layout, the layout walk has not visited the subtree below that render object, which means writes generated by building in that subtree cannot invalidate any information that has entered the layout calculation thus far. Similarly, once layout has returned from a render object, that render object will never be visited again during this layout, which means any writes generated by subsequent layout calculations cannot invalidate the information used to build the render object’s subtree.
就是因为对build和layout算法中的信息传播进行了严格控制,才有可能使build和layout交错。 具体来说,在build阶段,信息只能沿树传播。 当renderObject执行layout时,layout的遍历还尚未访问该渲染对象下的子树,这意味着在该子树中通过build生成的写入操作不会使到目前为止已进入layout计算的任何信息无效。 同样,一旦渲染对象return了layout,该渲染对象就不会在该layout期间再次被访问,这意味着后续layout计算生成的任何写入都不会无效化用于构建渲染对象的子树信息。

Additionally, linear reconciliation and tree surgery are essential for efficiently updating elements during scrolling and for modifying the render tree when elements are scrolled into and out of view at the edge of the viewport.
此外,“线性reconciliation(算法)”“树surgery” 对于在滚动过程中有效地更新element以及在viewport边缘将element滚动进出视图时修改渲染树至关重要。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值