上一篇
安卓应用开发怎么做移动动画
- 行业动态
- 2025-04-22
- 6
安卓移动动画基础
安卓移动动画主要分为以下三类实现方式:
动画类型 | 适用场景 | 特点 |
---|---|---|
补间动画(View Animation) | 简单平移/缩放/旋转/透明度变化 | 易实现但功能局限,仅支持View对象 |
属性动画(ObjectAnimator/AnimatorSet) | 复杂属性变化、路径运动 | 可动画任意属性,支持时间序列控制 |
过渡动画(Transition) | 场景切换、布局变化 | 自动处理多个视图的状态变化,适合Activity/Fragment切换 |
核心动画实现方式
补间动画实现移动
<!-res/anim/translate.xml --> <translate xmlns:android="http://schemas.android.com/apk/res/android" android:fromXDelta="0" android:toXDelta="300" android:duration="500"/>
// 加载动画并启动 Animation animation = AnimationUtils.loadAnimation(context, R.anim.translate); view.startAnimation(animation);
属性动画实现复杂移动
ObjectAnimator animator = ObjectAnimator.ofFloat(targetView, "x", 0f, 500f); animator.setDuration(1000); animator.setInterpolator(new AccelerateDecelerateInterpolator()); animator.start();
RecyclerView条目动画
// 设置添加/删除动画 ItemAnimator itemAnimator = new DefaultItemAnimator(); recyclerView.setItemAnimator(itemAnimator); // 自定义滑动位移监听 recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { // 根据dx/dy计算位移动画 } });
高级动画技巧
路径动画实现曲线移动
// 创建Path路径 Path path = new Path(); path.moveTo(startX, startY); path.cubicTo(controlX, controlY, endX, endY); // 创建动画 ObjectAnimator animator = ObjectAnimator.ofFloat(targetView, View.X, View.Y, path); animator.setDuration(2000); animator.start();
组合动画序列控制
AnimatorSet animatorSet = new AnimatorSet(); animatorSet.playTogether( ObjectAnimator.ofFloat(view, "scaleX", 0f, 1f), ObjectAnimator.ofFloat(view, "scaleY", 0f, 1f), ObjectAnimator.ofFloat(view, "alpha", 0f, 1f) ); animatorSet.setDuration(800); animatorSet.start();
使用Lottie实现复杂动画
// build.gradle依赖配置 implementation 'com.airbnb.android:lottie:5.2.0'
// 加载AE动画文件 LottieAnimationView animationView = findViewById(R.id.animation_view); animationView.setAnimation("animated_move.json");
性能优化要点
- 硬件加速:确保AndroidManifest中开启硬件加速
<application android:hardwareAccelerated="true">
- 减少视图层级:动画视图尽量扁平化,建议不超过5层嵌套
- 帧速率监控:使用
Choreographer
或 Android Studio Profiler 检测卡顿 - 缓存机制:对重复动画使用
ObjectAnimator.ofFloat().clone()
复用实例 - 异步处理:复杂计算放在
doAnimationFrame()
回调中执行
常见问题与解决方案
问题现象 | 解决方案 |
---|---|
动画执行时界面卡顿 | 启用硬件加速,将耗时操作移至子线程,使用 AnimatorUpdateListener 更新UI |
不同设备动画速度不一致 | 使用 ValueAnimator.setDuration() 统一时长,或根据密度动态计算参数 |
动画与手势冲突 | 在 GestureDetector 中优先处理触摸事件,暂停当前动画 |
低版本系统兼容性问题 | 使用条件判断加载特性(如VectorDrawable需5.0+) |
相关问题与解答
Q1:如何在动画过程中同步更新其他视图?
A1:通过 AnimatorUpdateListener
获取动画进度,在 onAnimationUpdate()
方法中实时修改关联视图。
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator valueAnimator) { float progress = (float) valueAnimator.getAnimatedValue(); textView.setAlpha(1 progress); // 根据动画进度同步改变透明度 } });
Q2:如何实现跨版本兼容的矢量动画?
A2:采用向下兼容方案:
- 使用
AnimatedVectorDrawable
(需5.0+) - 对低版本使用
VectorDrawableCompat
:if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { view.setBackground(context.getDrawable(R.drawable.animated_vector)); } else { view.setBackground(AppCompatResources.getDrawable(context, R.drawable.animated_vector_compat)); }