如何扩展FloatingView:创建自己的漂浮动画效果库

发布时间:2026/9/27 9:47:04

如何扩展FloatingView:创建自己的漂浮动画效果库
如何扩展FloatingView创建自己的漂浮动画效果库【免费下载链接】FloatingViewFloatingView can make the target view floating above the anchor view with cool animation项目地址: https://gitcode.com/gh_mirrors/fl/FloatingViewFloatingView是一个强大的Android动画库可以让任何视图在锚点视图上漂浮并展示酷炫的动画效果。如果你想让应用界面更加生动有趣掌握如何扩展FloatingView创建自定义动画效果库将是提升用户体验的关键技能。本文将为你详细介绍如何基于FloatingView架构构建属于自己的动画效果库让你的应用拥有独特的视觉体验。为什么需要自定义动画效果库FloatingView虽然提供了基础的缩放和位移动画但每个应用都有独特的设计语言和交互需求。通过创建自定义动画效果库你可以统一品牌视觉风格- 让动画效果与应用整体设计保持一致提升用户体验- 创建更符合用户预期的交互反馈增强产品差异化- 在众多应用中脱颖而出提高开发效率- 封装常用动画效果减少重复代码FloatingView核心架构解析要扩展FloatingView首先需要了解其核心架构。让我们看看项目的关键结构从类图中可以看到FloatingView的核心接口是FloatingTransition所有动画效果都通过实现这个接口来完成。这个设计模式使得扩展变得非常简单关键文件路径核心接口定义FloatingTransition.java动画控制器YumFloating.java内置动画效果ScaleFloatingTransition.java内置动画效果TranslateFloatingTransition.java创建自定义动画效果三步搞定第一步理解FloatingTransition接口创建自定义动画效果的第一步是理解FloatingTransition接口。这个接口非常简单只有一个方法public interface FloatingTransition { public void applyFloating(YumFloating yumFloating); }YumFloating对象提供了所有控制视图属性的方法包括透明度、缩放、旋转、位移等。第二步实现你的第一个动画效果让我们创建一个简单的旋转淡出动画作为示例public class RotateFadeTransition implements FloatingTransition { private long mDuration; private float mRotationAngle; public RotateFadeTransition() { mDuration 1000; mRotationAngle 360f; } public RotateFadeTransition(long duration, float rotationAngle) { this.mDuration duration; this.mRotationAngle rotationAngle; } 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()); } }); // 创建旋转动画 ValueAnimator rotateAnimator ObjectAnimator.ofFloat(0f, mRotationAngle); rotateAnimator.setDuration(mDuration); rotateAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { Override public void onAnimationUpdate(ValueAnimator valueAnimator) { yumFloating.setRotation((Float) valueAnimator.getAnimatedValue()); } }); // 启动动画 alphaAnimator.start(); rotateAnimator.start(); } }第三步使用自定义动画效果使用自定义动画效果非常简单FloatingElement builder new FloatingBuilder() .anchorView(anchorView) .targetView(targetView) .offsetX(0) .offsetY(0) .floatingTransition(new RotateFadeTransition(1500, 720f)) // 使用自定义动画 .build(); Floating floating new Floating(getActivity()); floating.startFloating(builder);高级动画效果设计技巧1. 组合动画效果你可以组合多个动画效果创建更丰富的视觉体验public class BounceScaleTransition implements FloatingTransition { Override public void applyFloating(final YumFloating yumFloating) { // 使用SpringHelper创建弹性动画 SpringHelper.createWithBouncinessAndSpeed(0.0f, 1.0f, 8, 12) .reboundListener(new SimpleReboundListener(){ Override public void onReboundUpdate(double currentValue) { float scale (float) currentValue; yumFloating.setScaleX(scale); yumFloating.setScaleY(scale); // 同时添加轻微旋转 yumFloating.setRotation(scale * 10); } }).start(yumFloating); } }2. 路径动画效果FloatingView提供了路径动画支持可以创建复杂的运动轨迹public class CurvePathTransition extends BaseFloatingPathTransition { Override public FloatingPath getFloatingPath() { Path path new Path(); // 创建贝塞尔曲线路径 path.moveTo(0, 0); path.quadTo(100, -200, 200, -100); path.quadTo(300, 0, 400, -150); return FloatingPath.create(path, PathPosition.ABSOLUTE); } Override public void applyFloatingPath(YumFloating yumFloating, float x, float y) { yumFloating.setTranslationX(x); yumFloating.setTranslationY(y); // 随着路径变化调整透明度 float progress x / 400f; yumFloating.setAlpha(1 - progress); } }3. 序列动画效果创建按顺序执行的动画序列public class SequentialTransition implements FloatingTransition { Override public void applyFloating(final YumFloating yumFloating) { // 第一步放大 ValueAnimator scaleUpAnimator ObjectAnimator.ofFloat(0f, 1.2f); scaleUpAnimator.setDuration(300); scaleUpAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { Override public void onAnimationUpdate(ValueAnimator valueAnimator) { float scale (Float) valueAnimator.getAnimatedValue(); yumFloating.setScaleX(scale); yumFloating.setScaleY(scale); } }); // 第二步缩小回正常 ValueAnimator scaleDownAnimator ObjectAnimator.ofFloat(1.2f, 1.0f); scaleDownAnimator.setDuration(200); scaleDownAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { Override public void onAnimationUpdate(ValueAnimator valueAnimator) { float scale (Float) valueAnimator.getAnimatedValue(); yumFloating.setScaleX(scale); yumFloating.setScaleY(scale); } }); // 第三步淡出 ValueAnimator fadeOutAnimator ObjectAnimator.ofFloat(1.0f, 0.0f); fadeOutAnimator.setDuration(500); fadeOutAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { Override public void onAnimationUpdate(ValueAnimator valueAnimator) { yumFloating.setAlpha((Float) valueAnimator.getAnimatedValue()); } }); // 设置动画序列 scaleUpAnimator.addListener(new AnimatorListenerAdapter() { Override public void onAnimationEnd(Animator animation) { scaleDownAnimator.start(); } }); scaleDownAnimator.addListener(new AnimatorListenerAdapter() { Override public void onAnimationEnd(Animator animation) { fadeOutAnimator.start(); } }); scaleUpAnimator.start(); } }构建动画效果库的最佳实践1. 统一配置管理创建配置类来统一管理动画参数public class AnimationConfig { public static final long DEFAULT_DURATION 1000; public static final float DEFAULT_BOUNCINESS 10; public static final float DEFAULT_SPEED 15; public static final float DEFAULT_TRANSLATE_Y -200f; // 品牌颜色动画配置 public static class Brand { public static final int PRIMARY_COLOR 0xFF3F51B5; public static final long BRAND_ANIM_DURATION 1200; } }2. 创建动画工厂使用工厂模式创建动画实例public class FloatingTransitionFactory { public static FloatingTransition createBounceTransition() { return new ScaleFloatingTransition( AnimationConfig.DEFAULT_DURATION, AnimationConfig.DEFAULT_BOUNCINESS, AnimationConfig.DEFAULT_SPEED ); } public static FloatingTransition createSlideUpTransition() { return new TranslateFloatingTransition( AnimationConfig.DEFAULT_TRANSLATE_Y, AnimationConfig.DEFAULT_DURATION ); } public static FloatingTransition createBrandTransition() { return new BrandFloatingTransition( AnimationConfig.Brand.PRIMARY_COLOR, AnimationConfig.Brand.BRAND_ANIM_DURATION ); } }3. 性能优化建议在创建动画效果库时注意以下性能优化使用对象池- 复用动画对象减少GC压力避免内存泄漏- 使用WeakReference持有View引用优化动画时长- 控制在1000ms以内最佳减少同时运行的动画- 避免过多动画同时执行实战案例创建电商应用动画库让我们创建一个电商应用常用的动画效果库// 添加到购物车动画 public class AddToCartTransition implements FloatingTransition { Override public void applyFloating(final YumFloating yumFloating) { // 模拟商品飞入购物车的抛物线轨迹 Path path new Path(); path.moveTo(0, 0); path.quadTo(150, -300, 300, 0); ValueAnimator pathAnimator ValueAnimator.ofFloat(0, 1); pathAnimator.setDuration(800); pathAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { Override public void onAnimationUpdate(ValueAnimator animation) { float fraction animation.getAnimatedFraction(); PathMeasure pm new PathMeasure(path, false); float[] pos new float[2]; pm.getPosTan(pm.getLength() * fraction, pos, null); yumFloating.setTranslationX(pos[0]); yumFloating.setTranslationY(pos[1]); // 添加旋转效果 yumFloating.setRotation(fraction * 360); // 逐渐缩小 yumFloating.setScaleX(1 - fraction * 0.5f); yumFloating.setScaleY(1 - fraction * 0.5f); } }); pathAnimator.start(); } } // 收藏动画 public class FavoriteTransition implements FloatingTransition { Override public void applyFloating(final YumFloating yumFloating) { // 心跳动画效果 ValueAnimator scaleAnimator ValueAnimator.ofFloat(1f, 1.3f, 1f); scaleAnimator.setDuration(600); scaleAnimator.setRepeatCount(2); scaleAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { Override public void onAnimationUpdate(ValueAnimator animation) { float scale (Float) animation.getAnimatedValue(); yumFloating.setScaleX(scale); yumFloating.setScaleY(scale); } }); // 颜色变化 if (yumFloating.getTargetView() instanceof TextView) { TextView textView (TextView) yumFloating.getTargetView(); ValueAnimator colorAnimator ObjectAnimator.ofArgb( Color.BLACK, Color.RED ); colorAnimator.setDuration(600); colorAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { Override public void onAnimationUpdate(ValueAnimator animation) { textView.setTextColor((Integer) animation.getAnimatedValue()); } }); colorAnimator.start(); } scaleAnimator.start(); } }测试与调试你的动画效果库1. 创建测试Activitypublic class AnimationTestActivity extends AppCompatActivity { private Floating mFloating; Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_test); mFloating new Floating(this); Button testButton findViewById(R.id.test_button); View anchorView findViewById(R.id.anchor_view); testButton.setOnClickListener(new View.OnClickListener() { Override public void onClick(View v) { // 测试不同的动画效果 testAnimation(new RotateFadeTransition()); testAnimation(new BounceScaleTransition()); testAnimation(new AddToCartTransition()); } }); } private void testAnimation(FloatingTransition transition) { // 创建测试视图 TextView testView new TextView(this); testView.setText(测试动画); testView.setBackgroundColor(Color.BLUE); testView.setTextColor(Color.WHITE); testView.setPadding(20, 10, 20, 10); // 构建动画 FloatingElement builder new FloatingBuilder() .anchorView(findViewById(R.id.anchor_view)) .targetView(testView) .floatingTransition(transition) .build(); mFloating.startFloating(builder); } }2. 性能监控使用Android Profiler监控动画性能检查内存使用情况监控帧率是否稳定在60fps查看CPU使用率总结与进阶建议通过本文的学习你已经掌握了如何扩展FloatingView创建自定义动画效果库的核心技能。记住以下关键点保持接口简洁- 所有动画效果都实现FloatingTransition接口充分利用YumFloating- 它提供了所有视图控制方法组合使用动画- 可以同时使用Android动画和Spring动画考虑性能- 避免创建过多动画对象及时清理资源进阶方向物理引擎集成- 集成物理引擎创建更真实的动画效果3D变换支持- 扩展支持3D旋转和透视变换粒子系统- 创建粒子爆炸、烟花等复杂效果Lottie集成- 支持After Effects动画导入现在就开始创建属于你自己的动画效果库吧通过自定义FloatingView动画你不仅能为用户带来更好的视觉体验还能让你的应用在众多竞品中脱颖而出。记住优秀的动画效果应该有明确的目的- 不是为了动画而动画⚡快速响应- 用户操作后立即反馈符合品牌- 与整体设计风格一致性能友好- 不影响应用流畅度开始你的动画创作之旅让应用界面活起来【免费下载链接】FloatingViewFloatingView can make the target view floating above the anchor view with cool animation项目地址: https://gitcode.com/gh_mirrors/fl/FloatingView创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

从2603到A6B:Leanstral模型进化史与1.5版本核心改进解析

从2603到A6B:Leanstral模型进化史与1.5版本核心改进解析

2026/8/23 1:06:24

从2603到A6B:Leanstral模型进化史与1.5版本核心改进解析 【免费下载链接】Leanstral-1.5-119B-A6B 项目地址: https://ai.gitcode.com/hf_mirrors/mistralai/Leanstral-1.5-119B-A6B Leanstral 1.5 119B A6B是Mistral AI推出的新一代开源代码代理模型&#…

Leanstral-1.5-119B-A6B推理参数调优:温度与推理努力度设置最佳实践

Leanstral-1.5-119B-A6B推理参数调优:温度与推理努力度设置最佳实践

2026/8/23 1:06:25

Leanstral-1.5-119B-A6B推理参数调优:温度与推理努力度设置最佳实践 【免费下载链接】Leanstral-1.5-119B-A6B 项目地址: https://ai.gitcode.com/hf_mirrors/mistralai/Leanstral-1.5-119B-A6B Leanstral-1.5-119B-A6B是一款专为Lean 4证明助手设计的开源代…

海气通量观测实践:4 类主流技术(卫星、浮标、船舶、系泊)的数据对比与融合挑战

海气通量观测实践:4 类主流技术(卫星、浮标、船舶、系泊)的数据对比与融合挑战

2026/8/23 1:06:25

海气通量观测实践:4类主流技术的数据对比与融合挑战海洋与大气之间的能量交换是地球气候系统的核心驱动力之一。潜热和感热通量的精确观测,不仅关乎天气预报的准确性,更是理解长期气候变化机制的关键。在这个领域,科研人员和工程师…

CANN/GE ACL数据集缓冲区添加函数

CANN/GE ACL数据集缓冲区添加函数

2026/9/26 19:14:12

aclmdlAddDatasetBuffer 【免费下载链接】ge GE(Graph Engine)是面向昇腾的图编译器和执行器,提供了计算图优化、多流并行、内存复用和模型下沉等技术手段,加速模型执行效率,减少模型内存占用。 GE 提供对 PyTorch、Te…

用ffmpeg高效批量调整图片尺寸的实战指南

用ffmpeg高效批量调整图片尺寸的实战指南

2026/9/27 1:30:29

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

Transformers 音频特征提取工具库 audio_utils 全解析:从 Mel 刻度换算到对数 Mel 频谱

Transformers 音频特征提取工具库 audio_utils 全解析:从 Mel 刻度换算到对数 Mel 频谱

2026/9/27 1:30:37

Transformers 音频特征提取工具库 audio_utils 全解析:从 Mel 刻度换算到对数 Mel 频谱 【免费下载链接】transformers 🤗 Transformers: the model-definition framework for state-of-the-art machine learning models in text, vision, audio, and mu…

RustFS 多节点集群重启与滚动升级实战:Readiness、Quorum 与 Degraded 模式完全指南

RustFS 多节点集群重启与滚动升级实战:Readiness、Quorum 与 Degraded 模式完全指南

2026/9/27 1:30:35

RustFS 多节点集群重启与滚动升级实战:Readiness、Quorum 与 Degraded 模式完全指南 【免费下载链接】rustfs 🚀2.3x faster than MinIO for 4KB object payloads. RustFS is an open-source, S3-compatible high-performance object storage system sup…

Java Integer缓存揭秘:128陷阱原理、避坑与面试全解

Java Integer缓存揭秘:128陷阱原理、避坑与面试全解

2026/9/27 1:30:34

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

RustFS Scanner 数据用量发布权威性决策:配额准入如何获得可用的权威依据

RustFS Scanner 数据用量发布权威性决策:配额准入如何获得可用的权威依据

2026/9/26 16:36:51

RustFS Scanner 数据用量发布权威性决策:配额准入如何获得可用的权威依据 【免费下载链接】rustfs 🚀2.3x faster than MinIO for 4KB object payloads. RustFS is an open-source, S3-compatible high-performance object storage system supporting mi…

远程协作的工作台整理

远程协作的工作台整理

2026/9/26 14:29:04

远程协作的工作台整理远程协作的核心不是再加一个工具,而是让交接信息足够完整。异步任务要写明目标、输入位置、完成标准和需要决策的人。 工作台的最小配置 将日程、待办、代码和沟通入口收拢到少数固定位置;通知按紧急程度分层。工作台不需要模仿办公…

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

2026/9/26 13:57:22

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

2026/9/26 23:35:16

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…