当前位置: 首页 > wzjs >正文

贴吧怎么做网站视频网络营销的十种方法

贴吧怎么做网站视频,网络营销的十种方法,网络营销的概念名词解释,周口做网站公司哪家好在阅读源码研究从第三方应用回到桌面的过程中,接触到RectFSpringAnim这个类,确认这个类就是最终动画的实现类。因此对这个类的源码进行阅读分析。 本文来详细分析 quickstep/src/com/android/quickstep/util/RectFSpringAnim.java 这个类。 核心作用 (…

在阅读源码研究从第三方应用回到桌面的过程中,接触到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.javaprotected 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? new TaskbarHotseatSpringConfig(mLauncher, closingWindowStartRectF, targetRect): new DefaultSpringConfig(mLauncher, mDeviceProfile, closingWindowStartRectF,targetRect));// Hook up floating views to the closing window animators.// note the coordinate of closingWindowStartRect is based on launcherRect closingWindowStartRect = new Rect();closingWindowStartRectF.round(closingWindowStartRect);Rect closingWindowOriginalRect =new Rect(0, 0, mDeviceProfile.widthPx, mDeviceProfile.heightPx);if (floatingIconView != null) {anim.addAnimatorListener(floatingIconView);floatingIconView.setOnTargetChangeListener(anim::onTargetPositionChanged);floatingIconView.setFastFinishRunnable(anim::end);FloatingIconView finalFloatingIconView = floatingIconView;// We want the window alpha to be 0 once this threshold is met, so that the// FolderIconView can be seen morphing into the icon shape.final float windowAlphaThreshold = 1f - SHAPE_PROGRESS_DURATION;RectFSpringAnim.OnUpdateListener runner = new SpringAnimRunner(targets, targetRect,closingWindowStartRect, closingWindowOriginalRect, startWindowCornerRadius) {@Overridepublic void onUpdate(RectF currentRectF, float progress) {finalFloatingIconView.update(1f, currentRectF, progress, windowAlphaThreshold,getCornerRadius(progress), false);super.onUpdate(currentRectF, progress);}};anim.addOnUpdateListener(runner);} else if (floatingWidget != null) {anim.addAnimatorListener(floatingWidget);floatingWidget.setOnTargetChangeListener(anim::onTargetPositionChanged);floatingWidget.setFastFinishRunnable(anim::end);final float floatingWidgetAlpha = isTransluscent ? 0 : 1;FloatingWidgetView finalFloatingWidget = floatingWidget;RectFSpringAnim.OnUpdateListener runner = new SpringAnimRunner(targets, targetRect,closingWindowStartRect, closingWindowOriginalRect, startWindowCornerRadius) {@Overridepublic void onUpdate(RectF currentRectF, float progress) {final float fallbackBackgroundAlpha =1 - mapBoundToRange(progress, 0.8f, 1, 0, 1, EXAGGERATED_EASE);final float foregroundAlpha =mapBoundToRange(progress, 0.5f, 1, 0, 1, EXAGGERATED_EASE);finalFloatingWidget.update(currentRectF, floatingWidgetAlpha, foregroundAlpha,fallbackBackgroundAlpha, 1 - progress);super.onUpdate(currentRectF, progress);}};anim.addOnUpdateListener(runner);} else {// If no floating icon or widget is present, animate the to the default window// target rect.anim.addOnUpdateListener(new SpringAnimRunner(targets, targetRect, closingWindowStartRect, closingWindowOriginalRect,startWindowCornerRadius));}// Use a fixed velocity to start the animation.animation.addListener(new AnimatorListenerAdapter() {@Overridepublic void onAnimationStart(Animator animation) {anim.start(mLauncher, mDeviceProfile, velocityPxPerS);}});return anim;}
  1. 提供窗口变换参数: 它的 OnUpdateListener (通常是 QuickstepTransitionManager.SpringAnimRunner 的实例) 在每一帧接收到计算好的 mCurrentRect。这个 mCurrentRect 就代表了应用窗口 Leash 在该帧应该呈现的大小和在 Launcher 坐标系下的位置
//quickstep/src/com/android/launcher3/QuickstepTransitionManager.java@Overridepublic void onUpdate(RectF currentRectF, float progress) {SurfaceTransaction transaction = new SurfaceTransaction();for (int i = mAppTargets.length - 1; i >= 0; i--) {RemoteAnimationTarget target = mAppTargets[i];SurfaceProperties builder = transaction.forSurface(target.leash);if (target.localBounds != null) {mTmpPos.set(target.localBounds.left, target.localBounds.top);} else {mTmpPos.set(target.position.x, target.position.y);}if (target.mode == MODE_CLOSING) {transferRectToTargetCoordinate(target, currentRectF, false, currentRectF);currentRectF.round(mCurrentRect);// Scale the target window to match the currentRectF.final float scale;// We need to infer the crop (we crop the window to match the currentRectF).if (mWindowStartBounds.height() > mWindowStartBounds.width()) {scale = Math.min(1f, currentRectF.width() / mWindowOriginalBounds.width());int unscaledHeight = (int) (mCurrentRect.height() * (1f / scale));int croppedHeight = mWindowStartBounds.height() - unscaledHeight;mTmpRect.set(0, 0, mWindowOriginalBounds.width(),mWindowStartBounds.height() - croppedHeight);} else {scale = Math.min(1f, currentRectF.height()/ mWindowOriginalBounds.height());int unscaledWidth = (int) (mCurrentRect.width() * (1f / scale));int croppedWidth = mWindowStartBounds.width() - unscaledWidth;mTmpRect.set(0, 0, mWindowStartBounds.width() - croppedWidth,mWindowOriginalBounds.height());}// Match size and position of currentRect.mMatrix.setScale(scale, scale);mMatrix.postTranslate(mCurrentRect.left, mCurrentRect.top);builder.setMatrix(mMatrix).setWindowCrop(mTmpRect).setAlpha(getWindowAlpha(progress)).setCornerRadius(getCornerRadius(progress) / scale);} else if (target.mode == MODE_OPENING) {mMatrix.setTranslate(mTmpPos.x, mTmpPos.y);builder.setMatrix(mMatrix).setAlpha(1f);}}mSurfaceApplier.scheduleApply(transaction);}
  1. 参数转换: SpringAnimRunner 接收到 mCurrentRect 后,会将其转换为应用到 SurfaceControl Leash 所需的 Matrix (变换矩阵,包含平移和缩放)、WindowCrop (裁剪区域) 和 CornerRadius (圆角)。
  2. 实现物理效果: 它使得窗口关闭动画不仅仅是简单的线性缩小和平移,而是带有速度感、惯性、可能的回弹或过冲效果,这得益于其底层的弹簧物理模型。这让过渡感觉更加生动和自然。
  3. 处理用户输入速度: 它能够接受用户手势结束时的速度作为输入,使得动画的初始状态能匹配用户的操作,增强了响应性。

总结:

RectFSpringAnim 是一个专门用于基于物理弹簧模型动画化矩形变换的工具类。在 Launcher3 中,它被 QuickstepTransitionManager 用来驱动应用关闭返回桌面时的窗口动画,通过模拟水平中心、垂直参考点和缩放进度的弹簧运动,计算出每一帧窗口应有的位置和大小,并将这些信息通过回调传递出去,最终应用到真实的窗口 Surface 上,实现了带有物理特性、流畅自然的过渡效果。

http://www.dtcms.com/wzjs/186255.html

相关文章:

  • seovip培训seo排名是什么
  • 网站关键词如何优化中国域名注册官网
  • 大江网站建设优化网站排名方法
  • 微山网站建设公司html简单网页成品
  • 南充做网站略奥网络免费推广app平台有哪些
  • 新手做电影网站广点通和腾讯朋友圈广告区别
  • 2017年做啥网站致富推广方案范例
  • 微信小程序官网下载seo系统推广
  • 北仑网站建设培训上海网站seo快速排名
  • wordpress jquery版本网络优化主要做什么
  • 动态网站开发期末考试答案网络推广发展
  • 论坛的网站开发项目快速排名怎么做
  • 网站服务器租用 配置今日新闻50字
  • 做百度推广去些网站加客户鄞州seo整站优化服务
  • 桂林创新大厦网站关键词优化技巧有哪些
  • 做一个php连接sql网站广州百度
  • 安徽建设厅网站进不去浏阳廖主任打人
  • 临西做网站哪里便宜360官方网站网址
  • 做网站要学java吗专业网店推广
  • 台州企业网站排名优化软文代写多少钱一篇
  • b2b电子商务网站归类广州网站seo地址
  • 潍坊做企业手机版网站品牌广告语经典100条
  • 成都网站asp access源码购买修改百度客服人工电话24
  • java网站开发是干什么百度浏览官网
  • 沈阳成创网站建设公司湖北seo网站推广
  • wordpress修改站点名百度推广账户登陆
  • 做海报去哪个网站找素材比较好呢怎么给产品找关键词
  • 怎么下学做衣服网站湖人今日排名最新
  • 搜索引擎手机动态网站制作设计今日国际新闻摘抄
  • wordpress 删除没用5g站长工具seo综合查询