
在 Android 开发中,帧动画是实现简单动态效果的常用方案,其原理类似传统电影胶卷——通过快速切换一组连续关联的静态图片,让人眼产生“连贯运动”的视觉错觉。比如加载动画、角色动作展示等场景,都可以通过 XML 定义帧动画快速实现。本文将从原理出发,结合完整代码示例,带大家掌握 Android 帧动画的开发流程。
帧动画的本质是“图片序列的定时切换”,核心逻辑包含两点:
与 GIF 图相比,XML 定义的帧动画更灵活(可动态控制开始/停止),且能更好地适配 Android 不同分辨率的设备。
帧动画的实现分为 3 个核心步骤:准备图片素材、编写 XML 动画配置、编写 Java 逻辑控制动画,具体流程如下:
将一组连续的静态图片(如 img_1.png、img_2.png……img_8.png)放入 res/drawable 文件夹中。注意:
在 res/drawable 文件夹下新建 XML 文件(如 anim_frame.xml),通过 <animation-list> 标签定义动画序列,每个 <item> 对应一帧图片及显示时长。
<?xml version="1.0" encoding="utf-8"?>
<!-- 根标签:animation-list 表示帧动画序列 -->
<animation-list
xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false"> <!-- oneshot=false 表示动画循环播放,true 表示只播放一次 -->
<!-- 每一个 item 对应一帧:drawable 为图片资源,duration 为显示时长(单位:毫秒) -->
<item
android:drawable="@drawable/img_1"
android:duration="200"/> <!-- 显示 200ms -->
<item
android:drawable="@drawable/img_2"
android:duration="200"/>
<item
android:drawable="@drawable/img_3"
android:duration="200"/>
<item
android:drawable="@drawable/img_4"
android:duration="200"/>
<item
android:drawable="@drawable/img_5"
android:duration="200"/>
<item
android:drawable="@drawable/img_6"
android:duration="200"/>
<item
android:drawable="@drawable/img_7"
android:duration="200"/>
<item
android:drawable="@drawable/img_8"
android:duration="200"/>
</animation-list>属性名 | 作用 | 可选值 |
|---|---|---|
| 控制动画是否循环播放 |
|
| 指定当前帧的图片资源 | 引用 |
| 指定当前帧的显示时长 | 正整数(单位:毫秒,如 200 表示显示 0.2 秒) |
在布局中使用 ImageView 作为动画的载体,因为帧动画本质是通过切换 ImageView 的背景/前景图片实现的。
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
<!-- 内边距配置,避免动画紧贴屏幕边缘 -->
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context=".MainActivity">
<!-- 用于展示帧动画的 ImageView -->
<ImageView
android:id="@+id/iv_animation"
android:layout_width="match_parent" <!-- 宽度占满父布局 -->
android:layout_height="match_parent" <!-- 高度占满父布局 -->
android:scaleType="fitCenter"/> <!-- 图片按比例缩放,居中显示 -->
</RelativeLayout>通过 AnimationDrawable 类获取 XML 中定义的动画配置,再通过 start()/stop() 方法控制动画的开始与停止。本文以“触屏触发动画”为例实现逻辑。
import android.graphics.drawable.AnimationDrawable;
import android.os.Bundle;
import android.view.MotionEvent;
import android.widget.ImageView;
import androidx.appcompat.app.AppCompatActivity; // 若使用旧版本可替换为 Activity
public class MainActivity extends AppCompatActivity {
// 声明 AnimationDrawable 对象,用于控制帧动画
private AnimationDrawable frameAnimation;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 1. 获取布局中的 ImageView 控件
ImageView ivAnimation = findViewById(R.id.iv_animation);
// 2. 将 XML 动画配置设置为 ImageView 的背景
ivAnimation.setBackgroundResource(R.drawable.anim_frame);
// 3. 从 ImageView 的背景中获取 AnimationDrawable 对象
frameAnimation = (AnimationDrawable) ivAnimation.getBackground();
}
/**
* 重写触屏事件:当用户触摸屏幕时,启动帧动画
* @param event 触屏事件对象
* @return 是否消费该事件
*/
@Override
public boolean onTouchEvent(MotionEvent event) {
// 判断是否为“手指按下”事件(MotionEvent.ACTION_DOWN)
if (event.getAction() == MotionEvent.ACTION_DOWN) {
// 检查动画是否已在运行,避免重复启动
if (!frameAnimation.isRunning()) {
frameAnimation.start(); // 启动动画
}
return true; // 消费该事件,避免事件传递给其他组件
}
return super.onTouchEvent(event);
}
}setBackgroundResource(R.drawable.anim_frame) 将 XML 动画配置与 ImageView 关联;(AnimationDrawable) ivAnimation.getBackground() 从 ImageView 的背景中提取 AnimationDrawable,该对象是帧动画的核心控制器;onTouchEvent 中监听“手指按下”事件,调用 frameAnimation.start() 启动动画;frameAnimation.isRunning() 判断动画是否正在运行,避免重复调用 start() 导致异常。AnimationDrawable 对象是否正确获取:需先设置 BackgroundResource,再获取背景,顺序不能颠倒;onCreate 中直接调用 start():onCreate 时 View 尚未完成绘制,直接启动可能无效,建议通过用户交互(如触屏、按钮点击)触发;drawable 文件夹中存在 img_1 至 img_8 的图片,且资源名与 XML 中一致。onDestroy)或动画无需继续播放时,调用 frameAnimation.stop() 停止动画,并释放资源:@Override
protected void onDestroy() {
super.onDestroy();
if (frameAnimation != null && frameAnimation.isRunning()) {
frameAnimation.stop();
}
}只需在 XML 动画配置的 <animation-list> 标签中添加 android:oneshot="true" 即可:
<animation-list
xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="true">
<!-- 帧配置... -->
</animation-list>XML 定义的帧动画适合实现轻量级动态效果,常见应用场景包括:
若需实现更复杂的动画(如骨骼动画、3D 动画),可考虑使用 Android 的 Property Animation(属性动画)或第三方库(如 Lottie),但帧动画在轻量级场景中仍具有“实现简单、性能开销低”的优势。
通过本文的步骤,你可以快速实现 Android 帧动画功能。关键在于理解“XML 配置帧序列 + Java 控制播放”的核心逻辑,再根据实际需求调整帧数、时长和触发方式。如果在开发中遇到问题,可检查资源配置或动画状态判断,确保每一步都符合 Android 帧动画的运行机制。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。