不一样角度带你了解 Flutter 中的滑动列表实现,谈谈Android-Binder机制及AIDL使用

从这个例子可以看出,RenderSliver 在实现可滑动列表的开销和逻辑上,会比直接使用 RenderBox 好和灵活很多,同时也是为什么 Viewport 里需要使用 RenderSliver 而不是 RenderBox 的原因。

⚠️注意,这里比较容易有一个误区,那就是 ListView 是由 Viewport + Scrollable 和一个RenderSliver 组成,所以在 ListView 里只会有一个 RenderSliver 而不是多个,想使用多个 RenderSliver 需要使用 CustomScrollView

最后顺便聊下 CustomScrollView ,事实上就是一个开放了可自定义配置 RenderSliver 数组的滑动控件,例如:

  • 通过利用 SliverList + SliverGrid 就可以搭配出多样化的滑动列表;
  • 通过 CupertinoSliverRefreshControl + SliverList 实现类似 iOS 原生的下拉刷新列表;

其他可用的内置 Sliver 还有:SliverPaddingSliverFillRemainingSliverFillViewportSliverPersistentHeaderSliverAppbar 等等。

NestedScrollView

为什么会把 NestedScrollView 单独拿出来说呢?这是因为 NestedScrollView 和前面介绍的滑动列表实现不大一样。

内部组成

如上图所示,NestedScrollView 内部主要是通过继承 CustomScrollView ,然后自定义一个 NestedScrollViewViewport 来实现联动的效果。

那这有什么特别的呢?如下代码所示,这是使用 NestedScrollView 常用的模式,那有看出什么特别的地方了吗?

代码里 NestedScrollViewbody 嵌套的是 ListView , 前面我们介绍了 ListView 本身就是 Viewport + Scrollable + SliverList 组合,而 NestedScrollView 本身也有 NestedScrollViewViewport

所以 NestedScrollView 的实现本质上其实就是 Viewport 嵌套 Viewport,会有两个 Scrollable 的存在 ,并且嵌套的 ListView 是被放在了 NestedScrollViewSliver 里面,大致如下图所示。

这里面有几个关键的对象,其中:

  • SliverFillRemaining :用于充满 Viewport 的剩余空间,在 NestedScrollView 里面就是充满 header 之外的剩余空间;

  • NestedScrollViewViewport : 在原 Viewport 的基础上增加了一个 SliverOverlapAbsorberHandle 参数,SliverOverlapAbsorberHandle 本身是一个 ChangeNotifier , 主要是用来当 markNeedsLayout 时对外发出通知,比如对 header 部分;

所以 NestedScrollView 本质上两个 Viewport 之间的嵌套,那他们之间是滑动关系是如何处理的?这就要说到 NestedScrollView 里的 _NestedScrollCoordinator 对象。

_NestedScrollCoordinator

_NestedScrollCoordinator 的实现比较复杂,简单地说 _NestedScrollCoordinator 内部创建了两个 _NestedScrollController

  • _outerController :属于 _NestedScrollViewCustomScrollViewcontroller ,也就是它自己 controller
  • _innerController :属于 bodycontroller

ListView 的父类 ScrollView 内部,默认情况下使用的就是 PrimaryScrollController.of(context) 这个 controller ,因为 PrimaryScrollController 是一个 InheritedWidget

而整个联动滑动的流程,主要就是 _NestedScrollCoordinator 里和它创建的两个 _NestedScrollController 有关系:

  • _NestedScrollController 的主要作用就是使用 _NestedScrollPosition 来替换 ScrollPosition

  • _NestedScrollCoordinator 将 _outer 和 _inner 两个 _NestedScrollController 组合起来(_outer 和 _inner 分别被应用到 NestedScrollViewbody);

  • _NestedScrollPosition 内部将 Drag 等手势操作传递回 _NestedScrollCoordinator 里。

  • 最后在 _NestedScrollCoordinatordragapplyUserOffset 等方法里进行内外滚动的分配;

SliverPersistentHeader

了解完 NestedScrollView 的布局和联动实现之外,最后简单介绍一下 SliverPersistentHeader , 因为经常在 NestedScrollView 里使用的 SliverAppBar,本质上 SliverAppBar 的实现靠的就是 SliverPersistentHeader

SliverPersistentHeader 主要是具备 floatingpinned 两个属性,它们的区别主要在于使用了不同的 RenderSliver 实现,而最终不同的地方其实就是输出 SliverGeometry 的不同

以第一个 _SliverFloatingPinnedPersistentHeader 和最后一个 _SliverScrollingPersistentHeader 之间的对比为例子,如下代码所示,在需要 floatingpinnedSliver 上,可以看到 paintExtentlayoutExtent 都有一个最小值。

所以 Sliver 被固定住的原理,其实就是 Viewport 得到了它的 paintExtentlayoutExtent 并不为 0,所以会继续为这个 Sliver 绘制对应区域的内容。

最后需要注意的是,当你使用 SliverPersistentHeader 去固定住头部的时候,作为 body 的列表是不知道顶部有个固定区域。 所以如果这时候不额外做一些处理,那么对于 body 而言,它的 paintOrigin 还是从最顶部开始而不是固定区域的下方。

如上动图所示,可以看到 item0 并没有在橙色区域停止滑动,而是继续往上滑动,这就是因为作为 body 的列表不知道顶部有固定区域。

总结

找工作是个很辛苦的事情,而且一般周期都比较长,有时候既看个人技术,也看运气。第一次找工作,最后的结果虽然不尽如人意,不过收获远比offer大。接下来就是针对自己的不足,好好努力了。

最后为了节约大家的时间,我把我学习所用的资料和面试遇到的问题和答案都整理成了PDF文档,都可以分享给有需要的朋友,如有需要私信我【资料】或者**【点这里】免费领取**

《Android面试复习资料汇总》

喜欢文章的话请关注、点赞、转发 谢谢!

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级安卓工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Android移动开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
img

习笔记、源码讲义、实战项目、讲解视频**
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
[外链图片转存中…(img-3Ze2ztQi-1711002922224)]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值