Android动画——逐帧动画
  Op9yysgqYUmV 2023年11月12日 24 0


1、概述


Android 平台有一套完整的动画框架,在Android3.0之前有两种动画,一种方式是补间动画 Tween Animation、另一种叫逐帧动画 Frame Animation(也称Drawable Animation )。这两种被归类为View Animation。 Android3.0以后增加了属性动画 Property Animation,这样子动画就分成两部分:


Android动画——逐帧动画_DrawableAnimation


2.使用


现在就从Drawable Animation开始说起吧。如上所述,Drawable Animation就是逐帧动画,如果大家看过老式的电影就很容易理解他的原理了,他就像电影胶带一样,按一定频率逐帧播放,使用它之前必须先定义好各个帧。在Android中逐帧动画需要得到AnimationDrawable类的支持,它位于"android.graphics.drawable.AnimationDrawable"包下,是Drawable的间接子类。它主要用来创建一个逐帧动画,并且可以对帧进行拉伸。在Android中提供了两种方式定义AnimationDrawable:XML定义资源文件和Java代码创建,采用XML的方式格式如下:

<?xml version="1.0" encoding="utf-8"?>
 
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"  
 
    android:oneshot="true"|"false">  
 
    <item android:drawable="@drawable/pic_name1" android:duration="integer" />  
 
    <item android:drawable="@drawable/pic_name2" android:duration="integer" />  
 
    <item android:drawable="@drawable/pic_name3" android:duration="integer" />  
 
    <item android:drawable="@drawable/pic_name4" android:duration="integer" />  
 
</animation-list>



其中android:oneshot属性控制该动画播放次数,等于true时则不会循环播放,否则循环播放。<item/>标签定义各个帧显示的图片,显示顺序依照<item/>定义顺序。 然后把AnimationDrawable对象设置为View的背景即可。Android下所有的资源文件均要放在/res目录下,对于动画帧的资源需要当成一个Drawable,所以需要把它放在/res/Drawable目录下。




使用Java代码创建帧动画的方式:通过创建AnimationDrawable对象,然后调用addFrame(Drawable frame,int duration)方法想动画中添加帧,它可以设置添加动画帧的Drawable和持续时间,每调用一次,就会向<animation-list .../>元素中添加一个<item.../>子元素。






下面写一个例子,模仿我们常见的加载界面,界面布局中只有一个居中的ImageView就不列出了。相对重要的是,我们需要定义一个xml文件描述各个帧,如下:


<?xml version="1.0" encoding="utf-8"?>
 
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
 
android:oneshot="false" >
 
<item
 
android:drawable="@drawable/l"
 
android:duration="500"/>
 
<item
 
android:drawable="@drawable/o"
 
android:duration="500"/>
 
<item
 
android:drawable="@drawable/a"
 
android:duration="500"/>
 
<item
 
android:drawable="@drawable/d"
 
android:duration="500"/>
 
<item
 
android:drawable="@drawable/i"
 
android:duration="500"/>
 
<item
 
android:drawable="@drawable/n"
 
android:duration="500"/>
 
<item
 
android:drawable="@drawable/g"
 
android:duration="500"/>
 

 
</animation-list>


只有AnimationDrawable对象还不能完成播放动画的功能,还需要AnimationDrawable其他的一些方法来操作逐帧动画,下面简单介绍一下AnimationDrawable的常用方法:


void start():开始播放逐帧动画。


void stop():停止播放逐帧动画。


void addFrame(Drawable frame,int duration):为AnimationDrawable添加一帧,并设置持续时间。


int getDuration(int i):得到指定index的帧的持续时间。


Drawable getFrame(int index):得到指定index的帧Drawable。


int getNumberOfFrames():得到当前AnimationDrawable的所有帧数量。


boolean isOneShot():当前AnimationDrawable是否执行一次,返回true执行一次,false循环播放。


boolean isRunning():当前AnimationDrawable是否正在播放。


void setOneShot(boolean oneShot):设置AnimationDrawable是否执行一次,true执行一次,false循环播放




Activity类如下:


public class DrawableAnimationActivity extends Activity {
 

 
private ImageView mImageViewLoading;
 
private ImageView mImageViewJava;
 
private AnimationDrawable loadingAnimation;
 
private AnimationDrawable javaAnimation;
 
private Button mButton;
 

 
@Override
 
protected void onCreate(Bundle savedInstanceState) {
 
// TODO Auto-generated method stub
 
super.onCreate(savedInstanceState);
 
setContentView(R.layout.activity_drawable_animation);
 
mImageViewLoading = (ImageView) findViewById(R.id.iv_drawable_loading);
 
mImageViewJava = (ImageView) findViewById(R.id.iv_drawable_java);
 
mButton = (Button) findViewById(R.id.btn_drawable_java);
 
loadingAnimation = (AnimationDrawable) mImageViewLoading
 
.getBackground();
 
// 采用java代码方式创建动画
 
mImageViewJava.setBackgroundResource(R.drawable.loading);
 
javaAnimation = (AnimationDrawable) mImageViewJava.getBackground();
 

 
mButton.setOnClickListener(new OnClickListener() {
 
@Override
 
public void onClick(View v) {
 
// TODO Auto-generated method stub
 
javaAnimation.start();
 
}
 
});
 
}
 

 
/**
 
* 触摸屏幕,结束动画
 
*/
 
public boolean onTouchEvent(MotionEvent event) {
 
if (event.getAction() == MotionEvent.ACTION_DOWN) {
 
loadingAnimation.stop();
 
return true;
 
}
 
return super.onTouchEvent(event);
 
}
 

 
/**
 
* activity显示到屏幕则开启动画
 
*/
 
@Override
 
public void onWindowFocusChanged(boolean hasFocus) {
 
// TODO Auto-generated method stub
 
super.onWindowFocusChanged(hasFocus);
 
if (hasFocus)
 
loadingAnimation.start();
 
}
 
}


实现的功能是:activity一启动,则动画开始,触摸屏幕时动画停止,代码比较容易理解,唯一需要注意的是,不能在onCreate()方法中调用AnimationDrawable的start()方法,因为此时AnimationDrawable还未真正加载到界面中。所以,如果想启动界面就自动运行动画,可以在OnWindowFocusChanged(boolean hasFocus)中启动动画。


效果如下:


Android动画——逐帧动画_android_02


使用Frame Animation注意以下问题:


  1. 要在代码中调用Imageview的setBackgroundResource方法,如果直接在XML布局文件中设置其src属性当触发动画时会强制退出。
  2. 在动画start()之前要先stop(),不然在第一次动画之后会停在最后一帧,这样动画就只会触发一次。
  3. 最后一点是SDK中提到的,不要在onCreate中调用start,因为AnimationDrawable还没有完全跟Window相关联,在onCreate()方法中,View并未完全显示(同理,在此方法中测量某个View的宽高,常得到0值。也同理SurfaceHolder要增加Callback方法)。如果想要界面显示时就开始动画的话,可以在onWindowFoucsChanged()中调用start()。

参考:


http://mikewang.blog.51cto.com/3826268/858171


http://www.2cto.com/kf/201312/261863.html




【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月12日 0

暂无评论

推荐阅读
  xaeiTka4h8LY   2024年05月17日   52   0   0 数据库JavaSQL
  2iBE5Ikkruz5   2023年12月12日   92   0   0 JavaJavaredisredis
Op9yysgqYUmV