【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 安装包,就可以…...

简易版抽奖活动的设计技术方案
1.前言 本技术方案旨在设计一套完整且可靠的抽奖活动逻辑,确保抽奖活动能够公平、公正、公开地进行,同时满足高并发访问、数据安全存储与高效处理等需求,为用户提供流畅的抽奖体验,助力业务顺利开展。本方案将涵盖抽奖活动的整体架构设计、核心流程逻辑、关键功能实现以及…...

黑马Mybatis
Mybatis 表现层:页面展示 业务层:逻辑处理 持久层:持久数据化保存 在这里插入图片描述 Mybatis快速入门  一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...

SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现
摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序,以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务,提供稳定高效的数据处理与业务逻辑支持;利用 uniapp 实现跨平台前…...

成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战
在现代战争中,电磁频谱已成为继陆、海、空、天之后的 “第五维战场”,雷达作为电磁频谱领域的关键装备,其干扰与抗干扰能力的较量,直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器,凭借数字射…...
AspectJ 在 Android 中的完整使用指南
一、环境配置(Gradle 7.0 适配) 1. 项目级 build.gradle // 注意:沪江插件已停更,推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...

Docker 本地安装 mysql 数据库
Docker: Accelerated Container Application Development 下载对应操作系统版本的 docker ;并安装。 基础操作不再赘述。 打开 macOS 终端,开始 docker 安装mysql之旅 第一步 docker search mysql 》〉docker search mysql NAME DE…...
Go语言多线程问题
打印零与奇偶数(leetcode 1116) 方法1:使用互斥锁和条件变量 package mainimport ("fmt""sync" )type ZeroEvenOdd struct {n intzeroMutex sync.MutexevenMutex sync.MutexoddMutex sync.Mutexcurrent int…...
Python+ZeroMQ实战:智能车辆状态监控与模拟模式自动切换
目录 关键点 技术实现1 技术实现2 摘要: 本文将介绍如何利用Python和ZeroMQ消息队列构建一个智能车辆状态监控系统。系统能够根据时间策略自动切换驾驶模式(自动驾驶、人工驾驶、远程驾驶、主动安全),并通过实时消息推送更新车…...
Caliper 负载(Workload)详细解析
Caliper 负载(Workload)详细解析 负载(Workload)是 Caliper 性能测试的核心部分,它定义了测试期间要执行的具体合约调用行为和交易模式。下面我将全面深入地讲解负载的各个方面。 一、负载模块基本结构 一个典型的负载模块(如 workload.js)包含以下基本结构: use strict;/…...