Android 常用动画梳理

Android 日常开发中为了页面美观,我们要实现控件的各种动画.Android系统提供了各种各样的动画来满足我们的需求.但是各种动画是满足不同需求的控件展示.以前开发只是用 没系统梳理过.最近实现直播用到各种各样的动画,再次梳理一下.

1:动画种类以及性能表现

以下是 Android 动画类型及其是否触发重绘、性能表现的对比表格:

Android 动画类型对比表(优化版)

动画类型 核心实现方式 是否触发重绘 性能表现 典型应用场景 示例类 / 属性
属性动画 修改 View 或对象属性(支持硬件加速) ✅ 是(多数) ⭐⭐⭐⭐ 平移、缩放、透明度、旋转 translationX/Y, scaleX/Y, alpha, ObjectAnimator
补间动画 修改 Canvas 的变换矩阵,不改变真实属性 ❌ 否 ⭐⭐⭐ 简单视觉动画(如淡入淡出) TranslateAnimation, AlphaAnimation, <scale>
帧动画 按帧切换图片资源(Bitmap) ✅ 是(每帧) 加载动画、帧动画特效 AnimationDrawable, <animation-list>
布局动画 布局变更时对子 View 应用动画 ✅ 是(布局) ⭐⭐ RecyclerView 增删动画 LayoutTransition, DefaultItemAnimator
矢量动画 动态修改 SVG 路径、颜色、属性 ✅ 是(矢量) ⭐⭐⭐⭐ 图标切换、菜单动效 AnimatedVectorDrawable, pathData, fillColor

2:动画介绍以及使用

2.1 属性动画(设置属性会重绘)

在 Android 开发中,属性动画(Property Animation) 是通过直接修改视图的属性(如位置、旋转角度、透明度等)来实现动画效果的机制.

核心类

  • ValueAnimator:计算属性值的变化,但不直接作用于对象,需手动更新属性。
  • ObjectAnimator :继承自 ValueAnimator,直接操作对象的属性,无需手动更新。
  • AnimatorSet:组合多个动画,支持并行或顺序播放。

重绘说明:

  • 属性动画默认基于 硬件加速 (Android 3.0+ 系统默认开启),通过 GPU 直接操作视图的属性(如位移、旋转等),无需通知 View 重新绘制自身

  • 如果动画修改的属性涉及 布局参数 (如 LayoutParams.width)或 内容更新 (如 TextView.setText()),则可能间接触发重绘。

scss 复制代码
1. 平移动画
val anim = ObjectAnimator.ofFloat(view, "translationX", 0f, 200f)
anim.duration = 500
anim.start()

2. 透明度动画
ObjectAnimator.ofFloat(view, "alpha", 1f, 0f).apply {
    duration = 800
    start()
}
3. 旋转动画
ObjectAnimator.ofFloat(view, "rotation", 0f, 360f).apply {
    duration = 1000
    interpolator = AccelerateDecelerateInterpolator()
    start()
}
4. 缩放动画
AnimatorSet().apply {
    playTogether(
        ObjectAnimator.ofFloat(view, "scaleX", 1f, 1.5f),
        ObjectAnimator.ofFloat(view, "scaleY", 1f, 1.5f)
    )
    duration = 500
    start()
}

5:组合动画 AnimatorSet
val move = ObjectAnimator.ofFloat(view, "translationX", 0f, 300f)
val fade = ObjectAnimator.ofFloat(view, "alpha", 1f, 0.5f)

AnimatorSet().apply {
    playSequentially(move, fade)  // 或 playTogether(...)
    duration = 1000
    start()
}

插值器说明:

插值器 效果
LinearInterpolator 匀速
AccelerateInterpolator 加速
DecelerateInterpolator 减速
BounceInterpolator 弹跳
OvershootInterpolator 超出再回弹

总结:

2.2 视图动画

在 Android 中,视图动画(View Animation) 是一个统称,包含了 补间动画(Tween Animation)帧动画(Frame Animation) 两种类型

视图动画是 Android 早期(API Level 1 开始支持)提供的动画系统,通过对 View 的视觉效果进行变换来实现动画,但 不改变 View 的实际属性(如布局参数、坐标值)

2.2.1 补间动画(不重绘)

补间动画是 Android 早期提供的一种动画机制,属于 View Animation 框架。通过在两个关键帧之间插值(tweening),实现 视觉上的动画效果,如平移、旋转、缩放、透明度等。

❗注意:补间动画只改变视觉,不改变 View 实际属性!

  • View 的 x/y、大小、点击区域都不会改变。
  • 不会触发 invalidate(),也不会重新布局

支持的动画类型

动画类型 类名 XML 标签 描述
平移动画 TranslateAnimation <translate> 视觉上左右上下移动
缩放动画 ScaleAnimation <scale> 放大缩小视图
旋转动画 RotateAnimation <rotate> 绕某点旋转
透明动画 AlphaAnimation <alpha> 淡入淡出
动画集合 AnimationSet <set> 多个动画组合一起播放

示例:

ini 复制代码
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromXDelta="0"
    android:toXDelta="100"
    android:duration="500"
    android:fillAfter="true" />

val anim = AnimationUtils.loadAnimation(context, R.anim.translate)
view.startAnimation(anim)


val animation = TranslateAnimation(0f, 300f, 0f, 0f).apply {
    duration = 1000
    fillAfter = true // 动画结束后保留状态(仅视觉)
}
view.startAnimation(animation)

注意事项

  • fillAfter = true:动画结束后保留视觉状态,但真实属性未改变。
  • 点击区域不会改变,即使视图"看起来"动了。
  • 不支持对非 View 对象(如数据类、属性值)做动画。

补间动画与属性动画的对比

对比项 补间动画(Tween) 属性动画(Property)
是否修改真实属性 ❌ 否 ✅ 是
是否触发重绘 ❌ 否 ✅ 是(多数情况)
动画目标限制 只能作用于 View 任意对象(包括非 UI)
控制粒度 较低 精细(自定义属性动画)
推荐程度 ❌ 过时 ✅ 推荐
2.2.2 帧动画

帧动画(Frame Animation)是通过依次播放一组静态图片(Drawable)来实现动画效果,就像"翻页书"或传统的手绘动画一样。

它是 Android 中最简单直接的动画方式,属于 Drawable Animation 范畴。

xml 复制代码
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
    android:oneshot="false"> <!-- false 表示循环播放 -->
    
    <item android:drawable="@drawable/frame1" android:duration="100" />
    <item android:drawable="@drawable/frame2" android:duration="100" />
    <item android:drawable="@drawable/frame3" android:duration="100" />
    <!-- 可继续添加更多帧 -->
</animation-list>

val imageView = findViewById<ImageView>(R.id.imageView)
imageView.setBackgroundResource(R.drawable.frame_anim)

val animationDrawable = imageView.background as AnimationDrawable
animationDrawable.start()

注意事项与缺点

  • 每帧一张图,占用内存大(尤其是高清图)
  • 不适合高帧率或复杂动画
  • 加载帧数多时容易 OOM,建议帧数量控制在合理范围(<30)或使用小尺寸图片
  • 不能在 XML 中设置延迟启动或自动停止

2.3 布局动画

布局动画是指当布局中的 子视图被添加、删除或位置变化 时,为这些变化应用过渡动画效果。

它是针对 ViewGroup 中的子元素 的动画处理,常见于如 RecyclerViewLinearLayoutGridLayout 等容器控件。

分类

类型 简介
LayoutAnimation 针对整个布局中子 View 的初始进入动画
LayoutTransition 针对 ViewGroup 在运行时添加/删除子 View 时的动画(更灵活)
RecyclerView 动画 Item 增删/移动动画,由 ItemAnimator 控制,属于布局动画的子集

核心特点对比

特性 LayoutAnimation LayoutTransition
适用时机 布局初始加载 动态添加、删除 View 时
控制粒度 针对所有子项统一应用 对添加、删除、改变分别可设置动画
使用难度 简单 中等
性能 中等(子项越多越慢) 中等
是否触发重绘 ✅ 是(布局变化引发重绘) ✅ 是
ini 复制代码
1:LayoutAnimation 使用方式(布局初次显示)

<alpha xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromAlpha="0"
    android:toAlpha="1"
    android:duration="500" />
    
 <layoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
    android:animation="@anim/layout_anim_fade"
    android:delay="0.2"
    android:order="normal" />

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layoutAnimation="@anim/layout_animation_controller">
    
    <!-- 子 View 如 Button、TextView 等 -->
</LinearLayout>

2:LayoutTransition 使用方式(动态添加/删除 View)

val layout = findViewById<LinearLayout>(R.id.myLayout)

val transition = LayoutTransition().apply {
    enableTransitionType(LayoutTransition.APPEARING)
    enableTransitionType(LayoutTransition.DISAPPEARING)
}
layout.layoutTransition = transition

// 动态添加 View
val newView = Button(this).apply { text = "新增" }
layout.addView(newView)

3: RecyclerView 布局动画

recyclerView.itemAnimator = DefaultItemAnimator()
recyclerView.itemAnimator = object : DefaultItemAnimator() {
    override fun animateAdd(holder: RecyclerView.ViewHolder?): Boolean {
        // 自定义添加动画
        return super.animateAdd(holder)
    }
}

2.4 矢量动画

矢量动画是基于 VectorDrawable 的动画,通过动态修改矢量图的路径、颜色、形状等属性,实现平滑、可缩放且清晰的动画效果。

它包含两种主要形式:

  • AnimatedVectorDrawable:对矢量图形进行属性动画(Path、颜色、变换等)
  • VectorDrawable:静态矢量图形,支持基本形状和渐变
核心特点
特性 描述
动画类型 基于矢量图形属性变化的动画
控制对象 AnimatedVectorDrawable 支持路径和属性动画
是否触发重绘 ✅ 是(每帧都会重绘矢量路径和颜色)
性能 ⭐⭐⭐⭐(矢量加硬件加速,性能优良)
兼容性 API 21+(支持库可向下兼容部分功能)
优点 文件小、无限缩放不失真、适合图标、按钮动画

示例:

ini 复制代码
1. 定义矢量图(res/drawable/ic_heart.xml)
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="24dp"
    android:height="24dp"
    android:viewportWidth="24"
    android:viewportHeight="24">
    <path
        android:name="heart"
        android:fillColor="#FF0000"
        android:pathData="M12,21.35L10.55,20.03 ..."/>
</vector>

2. 定义动画(res/animator/heart_path_morph.xml)
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1000"
    android:propertyName="pathData"
    android:valueFrom="M12,21.35L10.55,20.03 ..."
    android:valueTo="M12,19L10,17.5 ..."
    android:valueType="pathType"/>

val imageView = findViewById<ImageView>(R.id.imageView)
imageView.setImageResource(R.drawable.avd_heart)
3. 定义 AnimatedVectorDrawable(res/drawable/avd_heart.xml)
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/ic_heart">
    <target
        android:name="heart"
        android:animation="@animator/heart_path_morph" />
</animated-vector>


4. 在代码中使用
val drawable = imageView.drawable as AnimatedVectorDrawable
drawable.start()

注意事项

  • 动画属性要求是矢量路径或支持的可动画属性
  • 动画持续时间、插值器等都可自定义
  • 需注意兼容性,Android Support Library 提供 AnimatedVectorDrawableCompat 向下兼容
  • 路径动画对路径的点数和结构有要求,需匹配才能平滑过渡

3:常用动画库

  • Lottie:支持 AE 导出的 JSON 动画,实现复杂设计效果。
  • Glide/Coil:图片加载库自带淡入动画,可自定义。
  • Rebound:Facebook 弹性动画库,模拟物理效果。
  • ViewPropertyAnimator:简化版属性动画 API,链式调用更简洁。

4: 选择合适的动画系统

需求场景 推荐动画类型
简单过渡效果 视图动画 / 属性动画
复杂交互动画 属性动画
连续帧动画 帧动画 / Lottie
列表 / 网格元素动画 布局动画 / RecyclerView 动画
图标 / 状态切换 矢量动画
场景 / 页面切换 过渡动画

总结

Android常见动画,属性动画,补间动画(视图动画)帧动画(视图动画),布局动画,帧动画.按需索取,码字不容易 ,点个赞再走吧

相关推荐
hiii1 小时前
【ART 内存管理】堆内存分布与分配
android
张风捷特烈1 小时前
每日一题 Flutter#3 | 说说 Widget 的派生体系
android·flutter·面试
冰糖葫芦三剑客2 小时前
Android Studio 打包时遇到了签名报错问题:Invalid keystore format
android·ide·android studio
顾林海3 小时前
Android Native 内存泄漏检测全解析:从原理到工具的深度实践
android·面试·性能优化·源码·android虚拟内存
移动开发者1号4 小时前
详解图片内存占用的计算原理与代码验证(以500×500 PNG为例)
android·kotlin
移动开发者1号4 小时前
进程优先级与组件存活关系解析
android·kotlin
移动开发者1号4 小时前
你用对了吗Requestlayout,onlayout,onDraw,DrawChild
android·kotlin
快乐觉主吖6 小时前
Unity安卓平台开发,启动app并传参
android·unity·游戏引擎
原来如此。6 小时前
Android 轻松实现 增强版灵活的 滑动式表格视图
android
jiet_h11 小时前
Android Kotlin 算法详解:链表相关
android·算法·kotlin