AOSP Android14 Launcher3——RectFSpringAnim窗口动画类详解

在阅读源码研究从第三方应用回到桌面的过程中,接触到RectFSpringAnim这个类,确认这个类就是最终动画的实现类。因此对这个类的源码进行阅读分析。

本文来详细分析 quickstep/src/com/android/quickstep/util/RectFSpringAnim.java 这个类。

核心作用 (Core Purpose):

RectFSpringAnim 的核心作用是提供一个基于物理弹簧模型 (Spring Physics) 的动画机制,用于平滑地、带有物理惯性地将一个矩形 (RectF) 从起始状态 (位置和大小) 动画到目标状态 (位置和大小)

它主要用于 QuickstepTransitionManager 中处理**应用窗口关闭(返回桌面)**时的动画,模拟窗口从全屏状态自然地、带有速度感地收缩并移动到其在 Launcher 上的对应图标或小部件位置的过程。

工作原理 (How it Works):

与传统的基于时间插值器 (Time Interpolator) 的动画(如 ValueAnimator, ObjectAnimator) 不同,RectFSpringAnim 使用的是 AndroidX DynamicAnimation 库中的 SpringAnimation 和自定义的 FlingSpringAnim。其原理是:

  1. 分离动画维度: 它并不直接动画 RectF 的 left, top, right, bottom 四个值。而是将矩形的动画分解为三个独立的、但同时进行的物理模拟:

    • 水平中心 (RECT_CENTER_X): 使用 FlingSpringAnim 控制矩形水平中心点 (centerX) 的动画。FlingSpringAnim 结合了初始的抛掷 (Fling) 速度和最终稳定到目标值的弹簧 (Spring) 效果。
    • 垂直位置 (RECT_Y): 使用 FlingSpringAnim 控制矩形一个垂直参考点的动画。这个参考点由 mTracking 变量决定:
      • TRACKING_TOP: 动画矩形的 top 值。
      • TRACKING_BOTTOM: 动画矩形的 bottom 值。
      • TRACKING_CENTER: 动画矩形的 centerY 值。
        选择哪个参考点取决于动画的具体场景(例如,窗口是从屏幕上方移入还是下方移入,目标位置更靠近哪边)。
    • 缩放进度 (RECT_SCALE_PROGRESS): 使用标准的 SpringAnimation 控制一个从 0 到 1 的进度值 (mCurrentScaleProgress)。这个进度值随后被用来线性插值计算矩形当前的宽度和高度(从起始宽高到目标宽高)。
  2. 物理参数: 每个维度的弹簧动画都由物理参数控制:

    • Stiffness (刚度): 弹簧的“硬度”,影响回弹的速度和振荡频率。 (mStiffnessX, mStiffnessY, mRectStiffness)。
    • Damping Ratio (阻尼比): 控制振荡衰减的速度。值小于 1 会产生振荡,等于 1 是临界阻尼(最快到达且不振荡),大于 1 是过阻尼(缓慢到达)。(mDampingX, mDampingY)。
  3. 动画启动 (start 方法):

    • 接收一个初始速度 (velocityPxPerMs),通常是用户手指离开屏幕时的速度。
    • 对速度进行阻尼处理 (OverScroll.dampedScroll),防止过大的速度导致动画过于剧烈或不自然。
    • 根据起始/目标位置、阻尼后的速度、物理参数(刚度、阻尼比)创建并启动 RECT_CENTER_XRECT_YFlingSpringAnim
    • 根据Y轴速度和物理参数创建并启动 RECT_SCALE_PROGRESSSpringAnimation
    • 通知外部监听器动画开始。
  4. 动画更新 (onUpdate 方法):

    • 当任何一个底层的 SpringAnimationFlingSpringAnim 更新其值时,会触发其对应 FloatPropertyCompatsetValue 方法,进而调用 RectFSpringAnimonUpdate()
    • onUpdate() 中:
      • 根据当前的 mCurrentScaleProgress 插值计算出当前的宽度 (currentWidth) 和高度 (currentHeight)。
      • 根据当前的 mCurrentCenterX, mCurrentY 以及 mTracking 模式,结合计算出的 currentWidth, currentHeight重新构建出完整的 mCurrentRect (当前的矩形状态)。例如,如果 mTracking == TRACKING_TOP,则 mCurrentRect.top = mCurrentYmCurrentRect.bottom = mCurrentY + currentHeight
      • 遍历所有注册的 OnUpdateListener,调用它们的 onUpdate(mCurrentRect, mCurrentScaleProgress) 方法,将最新计算出的矩形状态和缩放进度传递出去。
  5. 动画结束 (maybeOnEnd 方法):

    • 每个底层的弹簧动画结束后,会设置对应的结束标志 (mRectXAnimEnded, mRectYAnimEnded, mRectScaleAnimEnded)。
    • maybeOnEnd() 会检查是否所有三个动画都已结束。
    • 只有当全部结束后,才会通知外部的 Animator.AnimatorListener 动画结束,并设置 setCanRelease(true)(用于 RemoteAnimationTargets 的资源释放检查)。
  6. 配置 (SpringConfig 子类):

    • 提供了不同的配置类(DefaultSpringConfig, TaskbarHotseatSpringConfig)来为不同的动画场景(如普通返回桌面 vs 返回到 Taskbar/Hotseat 上的图标)提供预设的、经过调整的物理参数(刚度、阻尼、追踪模式),以达到最佳的视觉效果。

在 Launcher3 中的作用:

RectFSpringAnim 在 Launcher3 (Quickstep) 中扮演着一个特定场景下的动画引擎角色:

  1. 驱动窗口关闭动画: 它是 QuickstepTransitionManager 在处理应用关闭返回桌面动画时的核心驱动力之一 (尤其是在 createWallpaperOpenAnimations -> getClosingWindowAnimators 中被创建和使用)。
// 应用关闭返回桌面动画
//quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
    protected RectFSpringAnim getClosingWindowAnimators(AnimatorSet animation,
            RemoteAnimationTarget[] targets, View launcherView, PointF velocityPxPerS,
            RectF closingWindowStartRectF, float startWindowCornerRadius) {
   
   
        FloatingIconView floatingIconView = null;
        FloatingWidgetView floatingWidget = null;
        RectF targetRect = new RectF();

		...... 省略
		
        boolean useTaskbarHotseatParams = mDeviceProfile.isTaskbarPresent && isInHotseat;
        //创建RectFSpringAnim动画实例
        RectFSpringAnim anim = new RectFSpringAnim(useTaskbarHotseatParams
                ? ne
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值