【Android】AnimationDrawable帧动画的实现

目录
引言
一、AnimationDrawable常用方法
1.1 导包
1.2 addFrame
1.3 setOneShot
1.4 start
1.5 stop
1.6 isRunning
二、 从xml文件获取并播放帧动画
2.1 创建XML文件
2.2 在布局文件中使用帧动画资源
三、在代码中生成并播放帧动画
3.1 addFrame加入帧动画列表
3.2 设置图像视图的图形为帧动画
四、代码示例
4.1 帧动画xml文件
4.2 FrameAnimActivity.java文件
4.3 activity_frame_anim.xml文件
4.4 实现效果
结语
引言
Android中动画分为三大类:帧动画、补间动画和属性动画。其中,帧动画是实现原理最简单的一种,跟现实生活中的电影胶卷类似,都是短时间内连续播放多张图片,从而模拟动态画面的效果。
一、AnimationDrawable常用方法
AnimationDrawable是 Android 框架中的一个类,用于在视图(如ImageView)中播放帧动画。帧动画是通过一系列静态图像(帧)的连续显示来创建动画效果的。AnimationDrawable类提供了加载和播放这些帧动画的功能。
1.1 导包
在使用 AnimationDrawable 之前你需要先引入必要的包
import android.graphics.drawable.AnimationDrawable;
1.2 addFrame
addFrame(Drawable frame, int duration):添加一幅图片帧,并指定该帧的持续时间(单位为毫秒)。
参数:
- frame:要添加的帧,类型为 Drawable 。
- duration:该帧显示的持续时间,单位为毫秒。
这个方法通常不是在运行时调用的,因为帧动画通常是在XML文件中定义的。但是,如果您想在代码中动态添加帧,可以使用此方法。
AnimationDrawable animation = new AnimationDrawable();
Drawable frame1 = getResources().getDrawable(R.drawable.frame1);
int duration1 = 100; // 持续时间,单位为毫秒
animation.addFrame(frame1, duration1);
// 继续添加其他帧...
1.3 setOneShot
setOneShot(boolean oneShot):设置动画是否只播放一次。
参数:
- oneShot:如果为true,则动画只播放一次;如果为false,则动画循环播放。
animation.setOneShot(true); // 只播放一次
// 或者
animation.setOneShot(false); // 循环播放
1.4 start
start():开始播放动画。
注意:在调用此方法之前,必须将 AnimationDrawable 设置为某个视图的背景或内容(例如ImageVIew 的 src)。
ImageView imageView = findViewById(R.id.imageView);
imageView.setImageResource(R.drawable.animation_list); // 假设animation_list是定义的帧动画XML文件
AnimationDrawable animation = (AnimationDrawable) imageView.getDrawable();
animation.start(); // 开始播放动画
1.5 stop
stop():停止播放动画。
animation.stop(); // 停止动画
1.6 isRunning
isRunning() :判断动画是否正在播放。
boolean isAnimating = animation.isRunning(); // 判断动画是否正在播放
if (isAnimating) {// 动画正在播放
} else {// 动画已停止
}
二、 从xml文件获取并播放帧动画
2.1 创建XML文件
在 res/drawable 目录下创建一个 XML 文件来定义帧动画。例如,创建一个名为 animation_list.xml的文件:
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"android:oneshot="false"> <!-- true 表示动画播放一次后停止,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>
在这个 XML 文件中,animation-list 是根元素,android:oneshot表示动画是否播放一次就停止,item 元素表示动画中的每一帧。android:drawable 属性指定帧的图像资源,android:duration 属性指定显示该帧的持续时间(以毫秒为单位)。
2.2 在布局文件中使用帧动画资源
在你的布局 XML 文件中,将 ImageView 的 src 属性设置为帧动画资源:
<ImageViewandroid:id="@+id/animated_view"android:layout_width="wrap_content"android:layout_height="wrap_content"android:src="@drawable/animation_list" />
三、在代码中生成并播放帧动画
3.1 addFrame加入帧动画列表
其中第一个参数要添加的帧图片需要替换成你自己的图片,第二个参数为该帧持续时间,单位为毫秒。
AnimationDrawable ad_frame = new AnimationDrawable(); // 创建一个帧动画图形
// 下面把每帧图片加入到帧动画的列表中
ad_frame.addFrame(getDrawable(R.drawable.flow_p1), 50);
ad_frame.addFrame(getDrawable(R.drawable.flow_p2), 50);
ad_frame.addFrame(getDrawable(R.drawable.flow_p3), 50);
ad_frame.addFrame(getDrawable(R.drawable.flow_p4), 50);
ad_frame.addFrame(getDrawable(R.drawable.flow_p5), 50);
ad_frame.addFrame(getDrawable(R.drawable.flow_p6), 50);
ad_frame.addFrame(getDrawable(R.drawable.flow_p7), 50);
ad_frame.addFrame(getDrawable(R.drawable.flow_p8), 50);
3.2 设置图像视图的图形为帧动画
// 设置帧动画是否只播放一次。为true表示只播放一次,为false表示循环播放
ad_frame.setOneShot(false);
// 设置图像视图的图形为帧动画
ImageView iv_frame_anim = findViewById(R.id.iv_frame_anim);
iv_frame_anim.setImageDrawable(ad_frame);
ad_frame.start(); // 开始播放帧动画
四、代码示例
以下是一个完整的示例,展示了如何在 Activity 中使用 AnimationDrawable :
4.1 帧动画xml文件
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"android:oneshot="false"><itemandroid:drawable="@drawable/flow_p1"android:duration="50" /><itemandroid:drawable="@drawable/flow_p2"android:duration="50" /><itemandroid:drawable="@drawable/flow_p3"android:duration="50" /><itemandroid:drawable="@drawable/flow_p4"android:duration="50" /><itemandroid:drawable="@drawable/flow_p5"android:duration="50" /><itemandroid:drawable="@drawable/flow_p6"android:duration="50" /><itemandroid:drawable="@drawable/flow_p7"android:duration="50" /><itemandroid:drawable="@drawable/flow_p8"android:duration="50" />
</animation-list>
4.2 FrameAnimActivity.java文件
package your.package.name;import android.graphics.drawable.AnimationDrawable;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import android.widget.ImageView;public class FrameAnimActivity extends AppCompatActivity {private ImageView iv_frame_anim; // 声明一个图像视图对象private AnimationDrawable ad_frame; // 声明一个帧动画对象@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_frame_anim);iv_frame_anim = findViewById(R.id.iv_frame_anim);iv_frame_anim.setOnClickListener(v -> {if (ad_frame.isRunning()) { // 判断帧动画是否正在播放ad_frame.stop(); // 停止播放帧动画} else {ad_frame.start(); // 开始播放帧动画}});showFrameAnimByCode(); // 在代码中生成并播放帧动画//showFrameAnimByXml(); // 从xml文件获取并播放帧动画}// 在代码中生成并播放帧动画private void showFrameAnimByCode() {ad_frame = new AnimationDrawable(); // 创建一个帧动画图形// 下面把每帧图片加入到帧动画的列表中ad_frame.addFrame(getDrawable(R.drawable.flow_p1), 50);ad_frame.addFrame(getDrawable(R.drawable.flow_p2), 50);ad_frame.addFrame(getDrawable(R.drawable.flow_p3), 50);ad_frame.addFrame(getDrawable(R.drawable.flow_p4), 50);ad_frame.addFrame(getDrawable(R.drawable.flow_p5), 50);ad_frame.addFrame(getDrawable(R.drawable.flow_p6), 50);ad_frame.addFrame(getDrawable(R.drawable.flow_p7), 50);ad_frame.addFrame(getDrawable(R.drawable.flow_p8), 50);// 设置帧动画是否只播放一次。为true表示只播放一次,为false表示循环播放ad_frame.setOneShot(false);// 设置图像视图的图形为帧动画iv_frame_anim.setImageDrawable(ad_frame);ad_frame.start(); // 开始播放帧动画}// 从xml文件获取并播放帧动画private void showFrameAnimByXml() {// 设置图像视图的图像来源为帧动画的XML定义文件iv_frame_anim.setImageResource(R.drawable.frame_anim);// 从图像视图对象中获取帧动画ad_frame = (AnimationDrawable) iv_frame_anim.getDrawable();ad_frame.start(); // 开始播放帧动画}}
4.3 activity_frame_anim.xml文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><ImageViewandroid:id="@+id/iv_frame_anim"android:layout_width="match_parent"android:layout_height="400dp"android:scaleType="fitStart" /></LinearLayout>
4.4 实现效果

结语
在深入探讨了AnimationDrawable类的各个方面后,我们可以清晰地看到它在Android动画创建中的重要作用。AnimationDrawable通过帧动画的方式,让开发者能够轻松地为应用添加生动有趣的视觉效果。然而,我们也必须认识到,在使用AnimationDrawable时,需要仔细考虑性能优化和生命周期管理,以确保动画的流畅播放和应用的稳定运行。总的来说,AnimationDrawable是一个功能强大且灵活的动画工具,值得开发者在合适的场景下加以利用。通过不断学习和实践,我们可以更好地掌握这一工具,为应用创造更加出色的动画效果。
相关文章:
【Android】AnimationDrawable帧动画的实现
目录 引言 一、AnimationDrawable常用方法 1.1 导包 1.2 addFrame 1.3 setOneShot 1.4 start 1.5 stop 1.6 isRunning 二、 从xml文件获取并播放帧动画 2.1 创建XML文件 2.2 在布局文件中使用帧动画资源 三、在代码中生成并播放帧动画 3.1 addFrame加入帧动画列…...
【消息序列】详解(7):剖析回环模式--设备测试的核心利器
目录 一、概述 1.1. 本地回环模式 1.2. 远程环回模式 二、本地回环模式(Local Loopback mode) 2.1. 步骤 1:主机进入本地环回模式 2.2. 本地回环测试 2.2.1. 步骤 2a:主机发送HCI数据包并接收环回数据 2.2.2. 步骤 2b&…...
解决Ubuntu 22.04系统中网络Ping问题的方法
在Ubuntu 22.04系统中,网络问题时有发生,尤其是当涉及到静态IP地址配置和网线直连的两台机器时。本文将探讨一种常见问题——断开并重新连接网线后,尽管网卡显示为UP状态,但无法立即ping通对方机器,以及如何解决这一问…...
【大数据学习 | Spark-SQL】Spark-SQL编程
上面的是SparkSQL的API操作。 1. 将RDD转化为DataFrame对象 DataFrame: DataFrame是一种以RDD为基础的分布式数据集,类似于传统数据库中的二维表格。带有schema元信息,即DataFrame所表示的二维表数据集的每一列都带有名称和类型。这样的数…...
15分钟做完一个小程序,腾讯这个工具有点东西
我记得很久之前,我们都在讲什么低代码/无代码平台,这个概念很久了,但是,一直没有很好的落地,整体的效果也不算好。 自从去年 ChatGPT 这类大模型大火以来,各大科技公司也都推出了很多 AI 代码助手ÿ…...
manim动画编程(安装+入门)
文章目录 1.基本介绍2.效果展示3.安装步骤3.1安装manba软件3.2配置环境变量3.3查看是否成功3.4什么是mamba3.5创建虚拟环境3.6尝试进入虚拟环境 4.vscode操作4.1默认配置文件 5.安装ffmpeg6.安装manim软件6.vscode制作7.我的学习收获 1.基本介绍 这个manim就是一款软件&#x…...
STL算法之数值算法<stl_numeric.h>
这一节介绍的算法,统称为数值(numeric)算法。STL规定,欲使用它们,客户端必须包含头文件<numeric>.SGI将它们实现与<stl_numeric.h>文件中。 目录 运用实例 accumulate adjacent_difference inner_product partial_sum pow…...
Oracle如何记录登录用户IP
在运维场景中,在定位到某个SQL引起系统故障之后,想知道是哪台机器发过来的,方便定位源头,该如何解决? 在 Oracle 数据库中记录登录用户的 IP 地址可以通过多种方法实现。以下是几种常见的方法,包括使用触发…...
Python图像处理:打造平滑液化效果动画
液化动画中的强度变化是通过在每一帧中逐渐调整液化效果的强度参数来实现的。在提供的代码示例中,强度变化是通过一个简单的线性插值方法来控制的,即随着动画帧数的增加,液化效果的强度也逐渐增加。 def liquify_image(image, center, radius…...
构建Ceph分布式文件共享系统:手动部署指南
#作者:西门吹雪 文章目录 micro-Services-TutorialCeph分布式文件共享方案部署Ceph集群使用CephCeph在kubernetes集群中的使用 micro-Services-Tutorial 微服务最早由Martin Fowler与James Lewis于2014年共同提出,微服务架构风格是一种使用一套小服务来开发单个应…...
数据结构——用数组实现栈和队列
目录 用数组实现栈和队列 一、数组实现栈 1.stack类 2.测试 二、数组实现队列 1.Queue类 2.测试 查询——数组:数组在内存中是连续空间 增删改——链表:链表的增删改处理更方便一些 满足数据先进后出的特点的就是栈,先进先出就是队列…...
vue3typescript,shims-vue.d.ts中declare module的vue声明
webpack已经有了vue-loader这些loader了,为什么还需要declare module *.vue’呢? declare module 是为了告诉 tsc 这是一个“模块”。 如果不声明, IDE 里因为 tsc 类型检查, lint 会标红。 但vue-loader 是在 Webpack 构建阶段使…...
C/C++基础知识复习(30)
1) 什么是 C 中的 Lambda 表达式?它的作用是什么? Lambda 表达式: 在 C 中,Lambda 表达式是一种可以定义匿名函数的机制,可以在代码中快速创建一个内联的函数对象,而不需要显式地定义一个函数。Lambda 表…...
【NLP 1、人工智能与NLP简介】
人人都不看好你,可偏偏你最争气 —— 24.11.26 一、AI和NLP的基本介绍 1.人工智能发展流程 弱人工智能 ——> 强人工智能 ——> 超人工智能 ① 弱人工智能 人工智能算法只能在限定领域解决特定的问题 eg:特定场景下的文本分类、垂直领域下的对…...
网络安全事件管理
一、背景 信息化技术的迅速发展已经极大地改变了人们的生活,网络安全威胁也日益多元化和复杂化。传统的网络安全防护手段难以应对当前繁杂的网络安全问题,构建主动防御的安全整体解决方案将更有利于防范未知的网络安全威胁。 国内外的安全事件在不断增…...
Swagger记录一次生成失败
最近在接入Swagger的时候遇到一个问题,就是Swagger UI可以使用的,但是/v3/docs 这个接口的json返回的base64类型的json,并不是纯json,后来检查之后是因为springboot3里面配置了json压缩。 Beanpublic HttpMessageConverters cusHt…...
Go 语言常用工具方法总结
在 Go 语言开发中,常常需要进行一些常见的类型转换、字符串处理、时间处理等操作。本文将总结一些常用的工具方法,帮助大家提高编码效率,并提供必要的代码解释和注意事项(go新人浅浅记录一下,以后来翻看🤣&…...
ThingsBoard规则链节点:GCP Pub/Sub 节点详解
目录 引言 1. GCP Pub/Sub 节点简介 2. 节点配置 2.1 基本配置示例 3. 使用场景 3.1 数据传输 3.2 数据分析 3.3 事件通知 3.4 任务调度 4. 实际项目中的应用 4.1 项目背景 4.2 项目需求 4.3 实现步骤 5. 总结 引言 ThingsBoard 是一个开源的物联网平台࿰…...
【Linux】select,poll和epoll
select,poll,epoll都是IO多路复用的机制。I/O多路复用就通过一种机制,可以监视多个描述符fd,一旦某个描述符就绪(一般是读就绪或者写就绪),系统会通知有I/O事件发生了(不能定位是哪一个)。但sel…...
Qt程序发布及打包成exe安装包
参考:Qt之程序发布以及打包成exe安装包 目录 一、简述 Qt 项目开发完成之后,需要打包发布程序,而因为用户电脑上没有 Qt 配置环境,所以需要将 release 生成的 exe 文件和所依赖的 dll 文件复制到一个文件夹中,然后再用 Inno Setup 打包工具打包成一个 exe 安装包,就可以…...
Better Godot MCP:用AI助手与Model Context Protocol提升Godot游戏开发效率
1. 项目概述:当AI助手遇上游戏引擎如果你是一名独立游戏开发者,或者正在学习使用Godot引擎,那么你肯定经历过这样的场景:脑子里有一个绝妙的游戏机制想法,但在实现时,却要花大量时间在编辑器里拖拽节点、编…...
别再自己编译zlib了!Qt自带zlib库的完整使用教程(附解压zip代码)
Qt开发者必知:无需编译直接调用内置zlib的完整实践指南 每次接手需要处理压缩文件的项目时,那种"又要折腾zlib编译"的恐惧感就会涌上心头。作为经历过无数次zlib编译失败的Qt开发者,我完全理解这种痛苦——直到发现Qt安装目录下那个…...
DownKyi哔哩下载姬:3分钟学会下载B站8K超高清视频的终极指南
DownKyi哔哩下载姬:3分钟学会下载B站8K超高清视频的终极指南 【免费下载链接】downkyi 哔哩下载姬downkyi,哔哩哔哩网站视频下载工具,支持批量下载,支持8K、HDR、杜比视界,提供工具箱(音视频提取、去水印等…...
Node.js GraphQL API 开发脚手架:基于TypeScript与Prisma的快速启动指南
1. 项目概述:一个为GraphQL API开发提速的“脚手架”如果你正在或即将开发一个基于Node.js的GraphQL API,并且厌倦了每次都要从零开始搭建项目结构、配置TypeScript、设置数据库连接、编写重复的样板代码,那么boilerplate-graphql这个项目就是…...
从视觉到动作:基于树莓派与OpenCV的智能抓取机器人实战指南
1. 项目概述与核心价值最近在GitHub上看到一个挺有意思的项目,叫“GlassesOpenClaw”。光看名字,你可能会有点摸不着头脑,这“眼镜”和“爪子”是怎么联系到一起的?其实,这是一个典型的开源硬件与计算机视觉结合的创意…...
别再只会看控制台了!用Docker+SEQ给你的.NET Core应用装个‘日志黑匣子’
构建企业级日志中枢:DockerSEQ在.NET Core中的高阶实践 当线上服务突然出现性能断崖式下跌时,大多数开发团队的第一反应是紧急翻查服务器控制台日志。这种救火式排查往往陷入两个困境:要么日志被滚动输出覆盖,关键错误信息消失无…...
simdjson-go与竞品对比:为什么选择这个高性能JSON解析器
simdjson-go与竞品对比:为什么选择这个高性能JSON解析器 【免费下载链接】simdjson-go Golang port of simdjson: parsing gigabytes of JSON per second 项目地址: https://gitcode.com/gh_mirrors/si/simdjson-go 在处理大规模JSON数据时,选择一…...
前后端跨域彻底弄懂:前端代理、Nginx线上部署、后端到底要不要配CORS?
文章目录一、前言二、先搞懂核心:什么是跨域?为什么后端才能根治?1. 跨域的本质:不是后端不让访问,是浏览器不让过2. 什么是CORS?三、本地开发环境:前端配Proxy代理,后端要不要管跨域…...
Grasscutter Tools:从零开始的原神私服图形化管理革命
Grasscutter Tools:从零开始的原神私服图形化管理革命 【免费下载链接】grasscutter-tools A cross-platform client that combines launcher, command generation, and mod management to easily play Grasscutter; 一个结合了启动器、命令生成、MOD管理等功能的跨…...
Grasscutter Tools:原神私服玩家的终极桌面助手,告别复杂命令行
Grasscutter Tools:原神私服玩家的终极桌面助手,告别复杂命令行 【免费下载链接】grasscutter-tools A cross-platform client that combines launcher, command generation, and mod management to easily play Grasscutter; 一个结合了启动器、命令生成…...
