赞
踩
最后顺便聊下 CustomScrollView
,事实上就是一个开放了可自定义配置 RenderSliver
数组的滑动控件,例如:
SliverList
+ SliverGrid
就可以搭配出多样化的滑动列表;CupertinoSliverRefreshControl
+ SliverList
实现类似 iOS 原生的下拉刷新列表;其他可用的内置 Sliver
还有:SliverPadding
、SliverFillRemaining
、SliverFillViewport
、SliverPersistentHeader
、SliverAppbar
等等。
为什么会把 NestedScrollView
单独拿出来说呢?这是因为 NestedScrollView
和前面介绍的滑动列表实现不大一样。
如上图所示,NestedScrollView
内部主要是通过继承 CustomScrollView
,然后自定义一个 NestedScrollViewViewport
来实现联动的效果。
那这有什么特别的呢?如下代码所示,这是使用 NestedScrollView
常用的模式,那有看出什么特别的地方了吗?
代码里 NestedScrollView
的 body
嵌套的是 ListView
, 前面我们介绍了 ListView
本身就是 Viewport
+ Scrollable
+ SliverList
组合,而 NestedScrollView
本身也有 NestedScrollViewViewport
。
所以 NestedScrollView
的实现本质上其实就是 Viewport
嵌套 Viewport
,会有两个 Scrollable
的存在 ,并且嵌套的 ListView
是被放在了 NestedScrollView
的 Sliver
里面,大致如下图所示。
这里面有几个关键的对象,其中:
SliverFillRemaining
:用于充满 Viewport
的剩余空间,在 NestedScrollView
里面就是充满 header
之外的剩余空间;
NestedScrollViewViewport
: 在原 Viewport
的基础上增加了一个 SliverOverlapAbsorberHandle
参数,SliverOverlapAbsorberHandle
本身是一个 ChangeNotifier
, 主要是用来当 markNeedsLayout
时对外发出通知,比如对 header 部分;
所以 NestedScrollView
本质上两个 Viewport
之间的嵌套,那他们之间是滑动关系是如何处理的?这就要说到 NestedScrollView
里的 _NestedScrollCoordinator
对象。
_NestedScrollCoordinator
的实现比较复杂,简单地说 _NestedScrollCoordinator
内部创建了两个 _NestedScrollController
:
_outerController
:属于 _NestedScrollViewCustomScrollView
的 controller ,也就是它自己 controller;_innerController
:属于 body
的 controller;在
ListView
的父类ScrollView
内部,默认情况下使用的就是PrimaryScrollController.of(context)
这个 controller ,因为PrimaryScrollController
是一个InheritedWidget
。
而整个联动滑动的流程,主要就是 _NestedScrollCoordinator
里和它创建的两个 _NestedScrollController
有关系:
_NestedScrollController
的主要作用就是使用 _NestedScrollPosition
来替换 ScrollPosition
;
_NestedScrollCoordinator
将 _outer 和 _inner 两个 _NestedScrollController
组合起来(_outer 和 _inner 分别被应用到 NestedScrollView
和 body
);
_NestedScrollPosition
内部将 Drag
等手势操作传递回 _NestedScrollCoordinator
里。
最后在 _NestedScrollCoordinator
的 drag
和 applyUserOffset
等方法里进行内外滚动的分配;
了解完 NestedScrollView
的布局和联动实现之外,最后简单介绍一下 SliverPersistentHeader
, 因为经常在 NestedScrollView
里使用的 SliverAppBar
,本质上 SliverAppBar
的实现靠的就是 SliverPersistentHeader
。
SliverPersistentHeader
主要是具备 floating
和 pinned
两个属性,它们的区别主要在于使用了不同的 RenderSliver
实现,而最终不同的地方其实就是输出 SliverGeometry
的不同。
以第一个 _SliverFloatingPinnedPersistentHeader
和最后一个 _SliverScrollingPersistentHeader
之间的对比为例子,如下代码所示,在需要 floating
和 pinned
的 Sliver
上,可以看到 paintExtent
和 layoutExtent
都有一个最小值。
所以 Sliver
被固定住的原理,其实就是 Viewport
得到了它的 paintExtent
和 layoutExtent
并不为 0,所以会继续为这个 Sliver
绘制对应区域的内容。
最后需要注意的是,当你使用 SliverPersistentHeader
去固定住头部的时候,作为 body
的列表是不知道顶部有个固定区域。 所以如果这时候不额外做一些处理,那么对于 body
而言,它的 paintOrigin
还是从最顶部开始而不是固定区域的下方。
如上动图所示,可以看到 item0 并没有在橙色区域停止滑动,而是继续往上滑动,这就是因为作为
body
的列表不知道顶部有固定区域。
这时候就可以通过使用SliverOverlapAbsorber
+SliverOverlapInjector
的组合来解决这个问题:
SliverPersistentHeader
的外层嵌套一个 SliverOverlapAbsorber
用于吸收 SliverPersistentHeader
的高度;SliverOverlapInjector
将这个高度配置到 body
列表中,让列表知道顶部存在一个固定高度的区域;自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级安卓工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Android移动开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
由于本文罗列的知识点是根据我自身总结出来的,并且由于本人水平有限,无法全部提及,欢迎大神们能补充~
将来我会对上面的知识点一个一个深入学习,也希望有童鞋跟我一起学习,一起进阶。
提升架构认知不是一蹴而就的,它离不开刻意学习和思考。
**这里,笔者分享一份从架构哲学的层面来剖析的视频及资料分享给大家,**梳理了多年的架构经验,筹备近1个月最新录制的,相信这份视频能给你带来不一样的启发、收获。
领取方式:点击这里获取免费架构视频资料
最近还在整理并复习一些Android基础知识点,有问题希望大家够指出,谢谢。
希望读到这的您能转发分享和关注一下我,以后还会更新技术干货,谢谢您的支持!
转发+点赞+关注,第一时间获取最新知识点
56601)**
最近还在整理并复习一些Android基础知识点,有问题希望大家够指出,谢谢。
希望读到这的您能转发分享和关注一下我,以后还会更新技术干货,谢谢您的支持!
转发+点赞+关注,第一时间获取最新知识点
Android架构师之路很漫长,一起共勉吧!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。