目录
[第十五章:Android 动画机制详解(属性动画、帧动画、过渡动画)](#第十五章:Android 动画机制详解(属性动画、帧动画、过渡动画))
[🔸 15.1 Android 动画机制分类](#🔸 15.1 Android 动画机制分类)
[🔸 15.2 帧动画 Frame Animation](#🔸 15.2 帧动画 Frame Animation)
[✦ 步骤:](#✦ 步骤:)
[🔸 15.3 补间动画 Tween Animation](#🔸 15.3 补间动画 Tween Animation)
[✦ 示例 XML 动画 res/anim/move.xml:](#✦ 示例 XML 动画 res/anim/move.xml:)
[✦ 使用方式:](#✦ 使用方式:)
[🔸 15.4 属性动画 Property Animation(推荐)](#🔸 15.4 属性动画 Property Animation(推荐))
[✦ 示例:平移动画](#✦ 示例:平移动画)
[✦ 支持属性:](#✦ 支持属性:)
[🔸 15.5 AnimatorSet 组合动画](#🔸 15.5 AnimatorSet 组合动画)
[🔸 15.6 属性动画监听器(动画回调)](#🔸 15.6 属性动画监听器(动画回调))
[🔸 15.7 ViewPropertyAnimator 简洁用法(链式)](#🔸 15.7 ViewPropertyAnimator 简洁用法(链式))
[🔸 15.8 过渡动画(Activity 界面切换)](#🔸 15.8 过渡动画(Activity 界面切换))
[✦ 配置过渡动画:](#✦ 配置过渡动画:)
[✅ 总结](#✅ 总结)
第十五章:Android 动画机制详解(属性动画、帧动画、过渡动画)
动画效果可以显著提升 Android 应用的用户体验,使界面更具吸引力和交互性。本章将详细介绍 Android 中三大主流动画技术:帧动画(Frame Animation)、视图动画(Tween Animation)和属性动画(Property Animation),重点讲解属性动画的原理和用法。
🔸 15.1 Android 动画机制分类
类型 | 说明 | 适用场景 |
---|---|---|
帧动画(Frame Animation) | 多张图片顺序播放 | 精灵动画、加载图 |
补间动画(Tween Animation) | 对视图的平移、缩放、旋转、透明度变换 | 简单界面过渡 |
属性动画(Property Animation) | 动画操作真正改变视图属性值 | 更强大、灵活,推荐使用 |
🔸 15.2 帧动画 Frame Animation
✦ 步骤:
- 在
res/drawable
下创建动画资源文件anim_frame.xml
:
XML
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="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>
- 设置给 ImageView:
java
ImageView imageView = findViewById(R.id.imageView);
imageView.setBackgroundResource(R.drawable.anim_frame);
AnimationDrawable animation = (AnimationDrawable) imageView.getBackground();
animation.start();
🔸 15.3 补间动画 Tween Animation
支持四种变换类型:
类型 | Java 类 | XML 标签 |
---|---|---|
位移 | TranslateAnimation |
<translate> |
缩放 | ScaleAnimation |
<scale> |
旋转 | RotateAnimation |
<rotate> |
透明度 | AlphaAnimation |
<alpha> |
✦ 示例 XML 动画 res/anim/move.xml
:
XML
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromXDelta="0" android:toXDelta="300"
android:duration="1000"/>
✦ 使用方式:
java
Animation anim = AnimationUtils.loadAnimation(this, R.anim.move);
imageView.startAnimation(anim);
⚠️ 补间动画只改变"视觉效果",不改变真正的属性值,如点击区域仍停留在原位置。
🔸 15.4 属性动画 Property Animation(推荐)
属性动画通过修改对象的属性值来实现动画效果,兼具"真实"和"灵活"两大特点。
✦ 示例:平移动画
java
ObjectAnimator animator = ObjectAnimator.ofFloat(imageView, "translationX", 0f, 500f);
animator.setDuration(1000);
animator.start();
✦ 支持属性:
属性 | 说明 |
---|---|
translationX/Y | 水平/垂直移动 |
scaleX/Y | 缩放 |
rotation / rotationX/Y | 旋转 |
alpha | 透明度 |
x / y | 精确坐标 |
🔸 15.5 AnimatorSet 组合动画
java
ObjectAnimator move = ObjectAnimator.ofFloat(view, "translationX", 0f, 300f);
ObjectAnimator fade = ObjectAnimator.ofFloat(view, "alpha", 1f, 0f);
AnimatorSet set = new AnimatorSet();
set.playTogether(move, fade); // 可选:playSequentially 顺序播放
set.setDuration(1000);
set.start();
🔸 15.6 属性动画监听器(动画回调)
java
animator.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) { }
@Override
public void onAnimationEnd(Animator animation) {
Toast.makeText(context, "动画结束", Toast.LENGTH_SHORT).show();
}
@Override
public void onAnimationCancel(Animator animation) { }
@Override
public void onAnimationRepeat(Animator animation) { }
});
🔸 15.7 ViewPropertyAnimator 简洁用法(链式)
java
imageView.animate()
.translationX(300)
.alpha(0.5f)
.setDuration(1000)
.withEndAction(() -> Toast.makeText(this, "完成", Toast.LENGTH_SHORT).show());
🔸 15.8 过渡动画(Activity 界面切换)
✦ 配置过渡动画:
java
overridePendingTransition(R.anim.slide_in_right, R.anim.slide_out_left);
用于在 startActivity()
或 finish()
后立即调用,修改页面切换效果。
✅ 总结
-
帧动画:适合静态图片连续播放,但资源占用大
-
补间动画:简单快速,适合临时效果,但无法改变属性值
-
属性动画:现代 Android 推荐使用方式,可操作任意属性值
-
可使用
AnimatorSet
组合动画,或用ViewPropertyAnimator
简化代码
小Demo
项目结构
Go
MainActivity.java
activity_main.xml
drawable/frame_animation.xml
AndroidManifest.xml
1. activity_main.xml
XML
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="点击按钮查看动画效果"
android:textSize="18sp"
android:gravity="center" />
<Button
android:id="@+id/btnPropertyAnimation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="属性动画示例" />
<Button
android:id="@+id/btnFrameAnimation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="帧动画示例" />
<Button
android:id="@+id/btnTransitionAnimation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="过渡动画示例" />
<!-- 用于显示动画的视图 -->
<ImageView
android:id="@+id/imageView"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_gravity="center_horizontal"
android:src="@drawable/ic_launcher_foreground" />
</LinearLayout>
2. MainActivity.java
java
package com.example.demo;
import android.os.Bundle;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import android.widget.ImageView;
import androidx.appcompat.app.AppCompatActivity;
import androidx.vectordrawable.graphics.drawable.Animatable2Compat;
public class MainActivity extends AppCompatActivity {
private ImageView imageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageView = findViewById(R.id.imageView);
Button btnPropertyAnimation = findViewById(R.id.btnPropertyAnimation);
Button btnFrameAnimation = findViewById(R.id.btnFrameAnimation);
Button btnTransitionAnimation = findViewById(R.id.btnTransitionAnimation);
// 属性动画示例
btnPropertyAnimation.setOnClickListener(v -> startPropertyAnimation());
// 帧动画示例
btnFrameAnimation.setOnClickListener(v -> startFrameAnimation());
// 过渡动画示例
btnTransitionAnimation.setOnClickListener(v -> startTransitionAnimation());
}
// 属性动画示例
private void startPropertyAnimation() {
imageView.animate()
.translationXBy(200f) // 水平移动 200px
.rotation(360f) // 旋转 360 度
.scaleX(1.5f) // X 轴缩放 1.5 倍
.scaleY(1.5f) // Y 轴缩放 1.5 倍
.setDuration(1000) // 动画持续 1 秒
.withEndAction(() -> {
// 动画结束后的回调
imageView.animate()
.translationXBy(-200f)
.rotation(0f)
.scaleX(1f)
.scaleY(1f)
.setDuration(1000)
.start();
})
.start();
}
// 帧动画示例
private void startFrameAnimation() {
imageView.setBackgroundResource(R.drawable.frame_animation);
((Animatable2Compat) imageView.getBackground()).start();
}
// 过渡动画示例
private void startTransitionAnimation() {
Animation animation = AnimationUtils.loadAnimation(this, R.anim.transition_animation);
imageView.startAnimation(animation);
}
}
3. drawable/frame_animation.xml
定义一个简单的帧动画:
XML
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false">
<item android:drawable="@drawable/frame_1" android:duration="200" />
<item android:drawable="@drawable/frame_2" android:duration="200" />
<item android:drawable="@drawable/frame_3" android:duration="200" />
<item android:drawable="@drawable/frame_4" android:duration="200" />
</animation-list>
注意:需要在
res/drawable
文件夹下准备几张图片(如frame_1.png
,frame_2.png
等)。
4. anim/transition_animation.xml
定义一个简单的过渡动画:
XML
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/accelerate_decelerate_interpolator">
<translate
android:fromXDelta="0%"
android:toXDelta="100%"
android:duration="1000" />
<alpha
android:fromAlpha="1.0"
android:toAlpha="0.0"
android:duration="1000" />
</set>
5. AndroidManifest.xml
XML
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.demo">
<application
android:allowBackup="true"
android:label="动画机制示例"
android:theme="@style/Theme.AppCompat.Light.DarkActionBar">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
代码说明
1. 属性动画
- 使用
ViewPropertyAnimator
实现平移、旋转和缩放。 - 提供流畅的链式调用,支持动画结束后的回调操作。
2. 帧动画
- 使用
AnimationDrawable
加载帧动画资源。 - 在
imageView
上设置背景,并通过start()
方法启动动画。
3. 过渡动画
- 使用 XML 定义平移和透明度变化的组合动画。
- 通过
AnimationUtils
加载动画资源并应用到ImageView
。
运行效果
-
属性动画示例:
- 点击按钮后,
ImageView
先向右平移、旋转、放大,再恢复原状。
- 点击按钮后,
-
帧动画示例:
- 点击按钮后,
ImageView
显示连续播放的帧动画。
- 点击按钮后,
-
过渡动画示例:
- 点击按钮后,
ImageView
向右移动并逐渐消失。
- 点击按钮后,
总结
- 属性动画 是最灵活的动画方式,适合动态控制视图属性。
- 帧动画 适用于播放一系列静态图片序列。
- 过渡动画 适合实现简单的视图变换效果,如平移、缩放、透明度变化等。