一、引言
动画是 Android 开发中非常重要的一部分,它不仅能提升界面效果,还能改善用户的操作体验。在开发中,动画的选择和使用可能会直接影响应用的流畅度和用户满意度。因此,了解 Android 提供的三种动画框架,并掌握它们的用法,是我们迈向开发进阶的重要一步。
二、入门实践
2.1帧动画
2.1.1帧动画介绍
Q: 什么是帧动画?
帧动画(Frame Animation)本质上是一种基于时间的逐帧动画技术。通过定义一组按顺序播放的图片(称为动画帧),并为每帧设定展示时间,使动画看起来流畅。
Q: 帧动画的工作原理是什么?
帧动画的核心是图片切换:准备一系列图片(帧),每帧代表动画中的某一状态;按设定的时间间隔依次切换这些图片,模拟出动态效果。动画完成后可以选择是否重复播放。
Q: 帧动画一般用于哪里?有什么优缺点?
帧动画适用于以下场景:
- UI 动效:例如加载指示器、按钮点击时的装饰性特效。
- 装饰性动画:用于角色行走、跳跃等简单动画。
- 短时特效:比如爆炸效果、烟雾特效。
优点:实现简单,适合展示已有的图片资源。不需要复杂的数学或物理知识,快速实现效果。
缺点:每一帧是单独的图片,占用大量内存,容易导致内存溢出。无法根据实时交互动态生成效果,缺乏灵活性。
2.1.1帧动画介绍
具体实现步骤
(1)准备图片资源
帧动画的核心是图片资源,需要一组连续的图片来构成动画帧。这些图片应存在 res/drawable 目录下,并且要保证图片尺寸和格式一致,以保证动画的流畅性。
(2)创建帧动画 XML 文件
在 res/drawable 目录下新建帧动画的 XML 文件,命名为 frame.xml。这个文件用来定义每一帧图片以及其展示时长。其中++android:drawable:++ 指定每一帧使用的图片资源。++android:duration:++每帧图片展示的时间,单位为毫秒,大家可以根据自己需求进行修改。示例如下:
XML
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/p2" android:duration="120"/>
<item android:drawable="@drawable/p3" android:duration="120"/>
<item android:drawable="@drawable/p4" android:duration="120"/>
<item android:drawable="@drawable/p5" android:duration="120"/>
<item android:drawable="@drawable/p6" android:duration="120"/>
</animation-list>
(3)布局文件定义
在布局文件中,将帧动画文件作为背景应用到一个视图组件。这里使用 RelativeLayout 容器。其中++android:background:++ 设置帧动画文件 frame.xml 作为视图的背景。
XML
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/rl"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/frame"
/>
(4)编写逻辑代码
在 MainActivity.java 中,通过 AnimationDrawable 类控制帧动画的启动和停止。其中AnimationDrawable: 用于操作帧动画的类,通过 start() 方法启动动画,**stop()**方法停止动画。点击事件: 用户点击布局时,切换动画的启动和停止状态。完整代码如下:
java
package com.example.animation;
import android.graphics.drawable.AnimationDrawable;
import android.os.Bundle;
import android.view.View;
import android.widget.RelativeLayout;
import androidx.appcompat.app.AppCompatActivity;
import com.example.animation.R;
public class MainActivity extends AppCompatActivity {
private boolean isPlaying = false; // 控制动画的播放状态
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 获取 RelativeLayout 容器
RelativeLayout relativeLayout = findViewById(R.id.rl);
// 将背景强制转换为 AnimationDrawable
AnimationDrawable animDrawable = (AnimationDrawable) relativeLayout.getBackground();
// 设置点击事件,切换动画播放状态
relativeLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (!isPlaying) {
animDrawable.start(); // 启动动画
isPlaying = true;
} else {
animDrawable.stop(); // 停止动画
isPlaying = false;
}
}
});
}
}
(5)运行演示
启动项目,点击图片,就可以看到我们所创建的帧动画了。

2.2视图动画
2.2.1视图动画介绍
Q: 视图动画是什么?
视图动画(View Animation)是一种对视图(View)进行的视觉效果变化,不会改变视图本身的布局或属性。通过视图动画,可以实现对视图的平移、旋转、缩放、透明度等效果,但这些变化仅在视觉上生效,不会修改视图的实际属性(例如坐标、大小等)。
Q: 视图动画有哪些常见应用场景?
视图动画通常用于简单的界面交互和动效设计,例如:
- 按钮点击效果:当用户点击按钮时,按钮可以实现缩放、旋转或透明度变化等效果。
- 页面切换动画:页面元素之间的滑动、淡入淡出等过渡动画。
- 用户反馈动画:如加载、成功、失败等状态反馈,常用透明度或旋转动画。
Q: 视图动画的实现方式是什么?
在 Android 中,视图动画通过 Animation 类实现。你可以通过 XML 或代码定义动画。XML 定义的动画文件更为简洁、可重用,而代码实现则提供了更多的灵活性。
常见的视图动画包括:
- Alpha动画:控制视图的透明度变化。
- Rotate动画:控制视图的旋转角度。
- Scale动画:控制视图的缩放效果。
- Translate动画:控制视图的位置移动。
2.2.2视图动画具体实现
现在,我们来一步一步实现一个简单的视图动画,给 ImageView 添加几个动画效果,包括透明度变化(alpha)、旋转(rotate)、缩放(scale)和位移(translate)。
(1)创建布局文件
首先,在 activity_main.xml 中,定义一个 ImageView,用于显示我们要应用动画的图片:
java
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/iv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:adjustViewBounds="true"
android:maxWidth="300dp"
android:maxHeight="300dp"
android:src="@drawable/ceshi" />
</RelativeLayout>
(2)创建动画文件并实现动画操作
1.透明度动画(Alpha Animation) 透明度动画会使视图从透明(alpha=0)渐变到不透明(alpha=1),或者反向过渡。
在 res/anim/ 目录下创建一个 XML 文件,命名为 alpha.xml,并写入以下内容:
XML
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<alpha
android:fromAlpha="0"
android:toAlpha="1"
android:duration="2000"/>
</set>
其中,++fromAlpha="0"指++ 起始透明度:0 = 完全透明,++toAlpha="1"++指结束透明度:1 = 完全不透明
在 MainActivity.java 中,我们加载并启动透明度动画。启动动画代码相同,只需要更换xml文件名称即可,后面就不再赘述了。
java
package com.example.donghua2;
import android.os.Bundle;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ImageView;
import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ImageView imageView = findViewById(R.id.iv);
imageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Animation animation = AnimationUtils.loadAnimation(MainActivity.this, R.anim.alpha);
imageView.startAnimation(animation);
}
});
}
}
启动项目后点击图片效果如下,可以发现图片在我们设置的两秒钟成功实现了由透明(alpha=0)渐变到不透明(alpha=1)的转变。

**2.旋转动画(Rotate Animation)**旋转动画让视图围绕某个点(通常是视图的中心)进行旋转。你可以设置旋转的起始角度和终止角度,以及旋转的持续时间。
在 res/anim/ 目录下创建一个 XML 文件,命名为 rotate.xml,并写入以下内容:
XML
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<rotate
android:fromDegrees="0"
android:toDegrees="360"
android:pivotX="50%"
android:pivotY="50%"
android:duration="2000"/>
</set>
其中pivotX="50%" / pivotY="50%":旋转中心点,控件正中心
在 MainActivity.java 中加载并启动旋转动画:
java
Animation animation1 = AnimationUtils.loadAnimation(MainActivity.this, R.anim.rotate);
imageView.startAnimation(animation1);
启动项目后我们可以发现初始状态:图片呈水平位置,点击图片后,图片进行绕着中心旋转一圈最后回到原来的水平位置。

**3. 缩放动画(Scale Animation)**缩放动画可以让视图在水平方向和垂直方向上进行缩放。你可以控制视图的初始和终止缩放比例。
在 res/anim/ 目录下创建一个 XML 文件,命名为 scale.xml,并写入以下内容:
XML
<set xmlns:android="http://schemas.android.com/apk/res/android">
<scale
android:fromXScale="1"
android:fromYScale="1"
android:toXScale="0.5"
android:toYScale="0.5"
android:pivotX="50%"
android:pivotY="50%"
android:duration="2000"/>
</set>
在 MainActivity.java 中加载并启动缩放动画:
java
Animation animation2 = AnimationUtils.loadAnimation(MainActivity.this, R.anim.scale);
imageView.startAnimation(animation2);
启动项目后可以观察到图片由原始大小缩小到了原始大小的50%。

**4. 位移动画(Translate Animation)**位移动画使视图从一个位置移动到另一个位置。你可以设置水平和垂直方向上的偏移量。
在 res/anim/ 目录下创建一个 XML 文件,命名为 translate.xml,并写入以下内容:
XML
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:fromXDelta="-350"
android:fromYDelta="-350"
android:toXDelta="350"
android:toYDelta="350"
android:duration="2000"/>
</set>
在 MainActivity.java 中加载并启动位移动画:
java
Animation animation3 = AnimationUtils.loadAnimation(MainActivity.this, R.anim.translate);
imageView.startAnimation(animation3);
运行项目后可以发现图片由左上角移动到了右下角的位置。

2.3属性动画
2.3.1属性动画介绍
Q: 什么是属性动画?
属性动画是 Android 动画框架中最强大的一种。它不仅能对视图的外观进行动画处理,还可以动态地改变对象的任意属性。属性动画通过 ObjectAnimator 或 ValueAnimator 来实现,对视图的具体属性进行动态变化,比如改变颜色、透明度、位置等。
Q: 属性动画和其他动画框架有什么区别?
与帧动画和视图动画不同,属性动画可以作用于任何对象的任何属性,甚至是非视图对象(如普通的 Java 对象)。属性动画提供了更多的灵活性,适用于复杂的动画需求,比如动态变化的位置、大小、透明度等。
Q: 常见的属性动画有哪几种?
ObjectAnimator:用于动画化视图的某个特定属性(例如位置、透明度、旋转、缩放等)。
ValueAnimator :用于执行数值的动画变化,适用于非视图对象或需要对数值进行更精细控制的情况。
2.3.2属性动画具体实现
在这部分,我们将通过一个简单的代码示例,来演示如何在 Android 中使用属性动画,具体包括 ObjectAnimator 和 ValueAnimator 的使用。
1. 使用 ValueAnimator:
ValueAnimator 是一种更基础的属性动画,它仅仅负责计算动画的数值变化,不直接作用于视图。我们通常可以通过 addUpdateListener 来监听动画的数值变化,并应用到界面的某个元素上。
java
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ImageView imageView = findViewById(R.id.iv);
ValueAnimator valueAnimator = ValueAnimator.ofFloat(0f, 1f);
valueAnimator.setDuration(2000);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float value = (float) animation.getAnimatedValue();
Log.d("leo", "onAnimationUpdate: " + value);
// 用动画值控制透明度
imageView.setAlpha(value);
}
});
valueAnimator.start();
}
}
假设我们在监听动画中透明度的值,启动项目在界面中透明度变化的同时,它的值从 0 变到 1,持续时间为 2 秒。每次动画更新时,会触发 onAnimationUpdate() 方法,并打印出当前的动画值。在日志输出内容中我们可以看到对应的输出内容。

2.使用 ObjectAnimator:
ObjectAnimator 是对视图属性的直接操作,它能直接对某个视图的属性进行动画化,比如透明度、位置、缩放等。下面代码创建了一个 ObjectAnimator 动画,指定目标视图为 TextView,动画的属性为 "alpha"(透明度)。这个动画的效果是让 TextView 从完全透明变为完全不透明,动画持续时间为 4 秒。
java
TextView textView = findViewById(R.id.tv); // 获取到目标视图
// 创建一个 ObjectAnimator,设置视图的透明度属性从 0 到 1
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(textView, "alpha", 0f, 1f);
objectAnimator.setDuration(4000); // 设置动画持续时间为 4 秒
objectAnimator.start(); // 启动动画
启动项目后展示如下,其实与视图动画中的透明度变化很类似,但是在属性动画中可以进行更复杂的属性配置。

3. 为动画添加监听器:
ObjectAnimator 和 ValueAnimator 都可以通过 AnimatorListener 或 AnimatorUpdateListener 来添加监听器,处理动画的不同阶段。通过 addListener() 方法,我们可以监听动画的开始、结束、取消和重复事件。例如,当动画开始时,我们可以在日志中打印"动画开始"。
java
objectAnimator.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(@NonNull Animator animator) {
Log.e("Animation", "动画开始");
}
@Override
public void onAnimationEnd(@NonNull Animator animator) {
Log.e("Animation", "动画结束");
}
@Override
public void onAnimationCancel(@NonNull Animator animator) {
Log.e("Animation", "动画取消");
}
@Override
public void onAnimationRepeat(@NonNull Animator animator) {
Log.e("Animation", "动画重复");
}
});
三、动画对比与场景选择
| 特性 | 视图动画(View Animation) | 帧动画(Frame Animation) | 属性动画(Property Animation) |
|---|---|---|---|
| 操作对象 | 仅限于 View 类的基本属性 |
通过图片帧实现动画 | 任意对象及其任意属性 |
| 动画类型 | 位移、缩放、旋转、透明度等 | 静态图片按顺序切换 | 任意属性(如颜色、透明度、路径等) |
| 性能消耗 | 较低(仅限 View 属性的更新) |
较高(需要加载和绘制多张图片) | 较高(涉及多个属性和复杂计算) |
| 适用场景 | 简单的 UI 动画、过渡效果 | 静态图像动画、图标动画 | 自定义复杂动画、路径动画、视图属性变化 |
| 灵活性 | 较低,无法对属性进行复杂控制 | 较低,仅限于图像切换 | 高,支持多种属性及动画形式 |
| 实现复杂度 | 简单,易于实现 | 简单,但内存占用大 | 复杂,需要配置对象和属性 |
选择建议
**视图动画:**如果需求是简单的界面动画,如按钮点击时的缩放、透明度变化,或者页面切换时的过渡动画,使用视图动画即可。
**帧动画:**适用于基于图像序列的动画,常见于图标动画、加载动画等,特别适合需要呈现多个静态图像的场景。
**属性动画:**当需要对对象的多个属性进行精细控制时,或者需要动态改变视图或对象的任意属性(如颜色、透明度、路径等),应选择属性动画。它支持更灵活和复杂的动画效果,适用于高级交互和自定义动画效果。