
FloatingView源码解析从FloatingBuilder到动画执行的完整流程【免费下载链接】FloatingViewFloatingView can make the target view floating above the anchor view with cool animation项目地址: https://gitcode.com/gh_mirrors/fl/FloatingView你是否曾经想要在Android应用中实现酷炫的漂浮动画效果FloatingView是一个强大的Android漂浮动画库能够让你的视图在锚点视图上方以酷炫的动画效果漂浮起来。本文将从源码层面深入解析FloatingView的实现机制带你了解从FloatingBuilder构建动画参数到最终动画执行的完整流程。FloatingView的核心功能是通过简单的API让任何视图实现漂浮动画效果。无论是点赞动画、分享动画还是其他需要视觉反馈的场景FloatingView都能轻松应对。让我们一起来看看这个优雅的动画库是如何实现的架构设计概览FloatingView采用了经典的建造者模式Builder Pattern和策略模式Strategy Pattern相结合的设计。整个架构分为三个主要层次配置层FloatingBuilder负责构建动画参数容器层Floating负责管理动画视图和生命周期动画层各种Transition实现具体的动画效果从上图可以看出FloatingView的核心类结构非常清晰。FloatingBuilder通过链式调用构建FloatingElementFloating负责将目标视图添加到悬浮层并执行动画而具体的动画效果则由实现了FloatingTransition接口的类来实现。核心组件深度解析1. FloatingBuilder建造者模式实现在FloatingViewLib/src/main/java/com/ufreedom/floatingview/FloatingBuilder.java中我们看到一个典型的建造者模式实现public class FloatingBuilder { private FloatingElement mFloatingElement; public FloatingBuilder() { mFloatingElement new FloatingElement(); mFloatingElement.targetViewLayoutResId -1; } public FloatingBuilder offsetX(int offsetX) { mFloatingElement.offsetX offsetX; return this; } public FloatingBuilder offsetY(int offsetY) { mFloatingElement.offsetY offsetY; return this; } public FloatingBuilder floatingTransition(FloatingTransition floatingTransition) { mFloatingElement.floatingTransition floatingTransition; return this; } public FloatingBuilder anchorView(View view){ mFloatingElement.anchorView view; return this; } public FloatingBuilder targetView(View view) { mFloatingElement.targetView view; return this; } public FloatingBuilder targetView(LayoutRes int layResId) { mFloatingElement.targetViewLayoutResId layResId; return this; } public FloatingElement build() { // 参数校验和默认值设置 if (mFloatingElement.floatingTransition null) { mFloatingElement.floatingTransition new ScaleFloatingTransition(); } return mFloatingElement; } }FloatingBuilder采用了经典的链式调用设计每个设置方法都返回this使得代码更加流畅易读。在build()方法中库还提供了默认的动画效果ScaleFloatingTransition这体现了良好的API设计原则。2. Floating容器类的精妙设计Floating类在FloatingViewLib/src/main/java/com/ufreedom/floatingview/Floating.java中实现是整个动画系统的核心容器。它的主要职责包括创建和管理悬浮装饰视图通过FloatingDecorView将目标视图添加到Activity的根布局中坐标计算和定位计算目标视图相对于锚点视图的位置动画启动调用具体的动画实现public void startFloating(FloatingElement floatingElement) { View anchorView floatingElement.anchorView; View targetView floatingElement.targetView; // 如果targetView为空则通过布局资源ID创建 if (targetView null){ targetView LayoutInflater.from(anchorView.getContext()) .inflate(floatingElement.targetViewLayoutResId,mFloatingDecorView,false); } // 计算锚点视图的全局位置 Rect rect new Rect(); anchorView.getGlobalVisibleRect(rect); int[] location new int[2]; mFloatingDecorView.getLocationOnScreen(location); rect.offset(-location[0], -location[1]); // 测量目标视图 int widthMeasureSpec View.MeasureSpec.makeMeasureSpec((1 30) - 1, View.MeasureSpec.AT_MOST); int heightMeasureSpec View.MeasureSpec.makeMeasureSpec((1 30) - 1, View.MeasureSpec.AT_MOST); targetView.measure(widthMeasureSpec,heightMeasureSpec); // 计算最终位置 int topMargin rect.top ((anchorView.getMeasuredHeight() - targetView.getMeasuredHeight()) / 2) floatingElement.offsetY; int leftMargin rect.left ((anchorView.getMeasuredWidth() - targetView.getMeasuredWidth()) / 2) floatingElement.offsetX; // 添加到悬浮层 FrameLayout.LayoutParams lp new FrameLayout.LayoutParams( ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); lp.topMargin topMargin; lp.leftMargin leftMargin; mFloatingDecorView.addView(targetView,lp); // 执行动画 FloatingTransition floatingAnimator floatingElement.floatingTransition; floatingAnimator.applyFloating(new YumFloating(targetView, mSpringSystem)); }这段代码展示了FloatingView如何精确计算目标视图的位置。通过getGlobalVisibleRect()获取锚点视图的全局坐标然后根据悬浮装饰视图的位置进行偏移确保目标视图能够准确地显示在锚点视图上方。3. 动画系统设计FloatingView的动画系统采用了策略模式通过FloatingTransition接口定义了统一的动画执行方法public interface FloatingTransition { public void applyFloating(YumFloating yumFloating); }这个简单的接口设计使得动画效果可以轻松扩展。让我们看看几个具体的动画实现ScaleFloatingTransition缩放动画在FloatingViewLib/src/main/java/com/ufreedom/floatingview/effect/ScaleFloatingTransition.java中public class ScaleFloatingTransition implements FloatingTransition { Override public void applyFloating(final YumFloating yumFloating) { // 透明度动画 ValueAnimator alphaAnimator ObjectAnimator.ofFloat(1.0f, 0.0f); alphaAnimator.setDuration(mDuration); alphaAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { Override public void onAnimationUpdate(ValueAnimator valueAnimator) { yumFloating.setAlpha((Float) valueAnimator.getAnimatedValue()); } }); alphaAnimator.start(); // 缩放动画使用Facebook Rebound物理引擎 SpringHelper.createWithBouncinessAndSpeed(0.0f, 1.0f, mBounciness, mSpeed) .reboundListener(new SimpleReboundListener(){ Override public void onReboundUpdate(double currentValue) { yumFloating.setScaleX((float) currentValue); yumFloating.setScaleY((float) currentValue); } }).start(yumFloating); } }ScaleFloatingTransition结合了Android原生的ValueAnimator和Facebook的Rebound物理引擎创建了既有流畅性又有物理感的动画效果。路径动画实现对于更复杂的路径动画FloatingView提供了BaseFloatingPathTransition基类。让我们看看路径动画的关键实现public abstract class BaseFloatingPathTransition implements FloatingPathTransition { public PathPosition getFloatingPosition(float progress) { if (mPathPosition null){ mPathPosition new PathPosition(); } if (mPathPositionGetter null){ mPathPositionGetter new float[2]; } if (getFloatingPath() ! null){ // 获取路径上指定进度的坐标 getFloatingPath().getPathMeasure().getPosTan(progress, mPathPositionGetter, null); mPathPosition.x mPathPositionGetter[0]; mPathPosition.y mPathPositionGetter[1]; } return mPathPosition; } }这个基类使用了Android的PathMeasure类来精确计算路径上任意点的坐标为自定义路径动画提供了坚实的基础。4. YumFloating视图包装器YumFloating类在FloatingViewLib/src/main/java/com/ufreedom/floatingview/transition/YumFloating.java中定义它起到了桥梁作用视图操作代理将动画属性应用到实际的目标视图物理引擎集成封装了Facebook Rebound物理引擎的创建和使用资源管理提供clear()方法清理视图资源public class YumFloating implements ITransition, Rebound { private WeakReferenceView mTargetViewWeakReference; public void setAlpha(float alpha) { View targetView; if ((targetView getTargetView()) ! null){ targetView.setAlpha(alpha); } } public Spring createSpringByBouncinessAndSpeed(double bounciness, double speed) { return mSpringSystem.createSpring() .setSpringConfig(SpringConfig.fromBouncinessAndSpeed(bounciness, speed)); } public void clear(){ View view getTargetView(); if (view ! null){ ViewParent viewParent view.getParent(); if (viewParent instanceof ViewGroup){ ViewGroup parent (ViewGroup) viewParent; parent.removeView(view); mTargetViewWeakReference.clear(); } } } }使用WeakReference来持有目标视图是一个很好的设计选择它避免了内存泄漏问题同时允许在需要时自动清理资源。动画执行流程详解了解了各个组件的实现后让我们看看完整的动画执行流程第一步构建动画参数用户通过FloatingBuilder链式调用设置锚点视图、目标视图、偏移量和动画效果。第二步创建Floating容器通过new Floating(activity)创建动画容器内部会创建FloatingDecorView并添加到Activity的根布局中。第三步计算视图位置Floating容器计算目标视图相对于锚点视图的精确位置考虑到了全局坐标转换和视图尺寸差异。第四步添加视图到悬浮层将目标视图添加到FloatingDecorView中使用计算出的位置参数。第五步执行动画调用具体的FloatingTransition实现通过YumFloating包装器将动画属性应用到目标视图。第六步资源清理动画结束后YumFloating的clear()方法会从父视图中移除目标视图释放相关资源。设计亮点与最佳实践1. 灵活的扩展机制FloatingView的动画系统设计得非常灵活。开发者可以实现FloatingTransition接口创建自定义动画继承BaseFloatingPathTransition实现复杂的路径动画通过SpringHelper或直接使用Rebound物理引擎创建物理动画2. 内存管理优化使用WeakReference避免内存泄漏提供clear()方法手动清理资源自动从父视图移除动画视图3. 坐标计算的精确性通过getGlobalVisibleRect()和getLocationOnScreen()的组合使用确保在不同屏幕尺寸和滚动位置下都能准确定位。4. 物理动画支持集成Facebook Rebound物理引擎提供自然的弹簧动画效果增强了用户体验。实际应用示例让我们通过一个简单的示例来看看如何使用FloatingView// 创建漂浮动画元素 FloatingElement element new FloatingBuilder() .anchorView(anchorView) // 锚点视图 .targetView(targetView) // 目标视图 .offsetX(20) // X轴偏移 .offsetY(-30) // Y轴偏移 .floatingTransition(new ScaleFloatingTransition()) // 动画效果 .build(); // 创建漂浮容器并执行动画 Floating floating new Floating(activity); floating.startFloating(element);性能优化建议视图复用对于频繁使用的漂浮动画考虑复用目标视图动画时长控制根据场景调整动画时长避免过长影响用户体验资源及时释放在不需要时调用YumFloating.clear()释放资源避免过度绘制确保目标视图不会过度复杂影响动画性能总结FloatingView通过精心的架构设计将复杂的漂浮动画实现封装成了简单易用的API。从FloatingBuilder的建造者模式到Floating的容器管理再到各种Transition的动画实现每一层都体现了良好的设计原则。这个库的成功之处在于简洁的API设计链式调用让代码更加直观灵活的扩展机制支持自定义动画效果优秀的性能表现合理的资源管理和坐标计算良好的兼容性支持Android 3.0及以上版本无论你是想要实现点赞动画、分享动画还是其他需要视觉反馈的场景FloatingView都是一个值得考虑的解决方案。通过本文的源码解析相信你已经对FloatingView的内部机制有了深入的理解可以更好地在自己的项目中应用这个强大的动画库了希望这篇源码解析能帮助你更好地理解和使用FloatingView。如果你有更多关于Android动画实现的问题欢迎继续探索FloatingView的源码相信你会发现更多有趣的设计细节【免费下载链接】FloatingViewFloatingView can make the target view floating above the anchor view with cool animation项目地址: https://gitcode.com/gh_mirrors/fl/FloatingView创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考