Drawable动画
标签: Android
也可以称作帧动画,就是一系列的Drawable资源依次绘制出来,形成的动画效果。
AnimationDrawable 的基本类是AnimationDrawable 。
AnimationDrawable是一个Drawable而不是Animation,其类的继承关系如下:
android.graphics.drawable.Drawable
android.graphics.drawable.DrawableContainer
android.graphics.drawable.AnimationDrawable
和View动画一样,可以通过XML和硬编码两种方式来定义Drawable动画。
XML形式
xml文件建议放在 res/drawable/目录下,文件的形式如下:
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="true">
<item android:drawable="@drawable/drawableXX" android:duration="200" />
<item android:drawable="@drawable/drawableYY" android:duration="200" />
</animation-list>
android:oneshot是指该动画是只播放一次还是循环播放。
每个item标签指明了其中的一个帧,内部包括android:drawable和android:duration分别代表播放的drawable资源和停留时间。
常用API
Modifier and Type | Method | Description |
---|---|---|
void | addFrame(Drawable frame, int duration) | 添加一帧到动画 |
int | getDuration(int i) | |
Drawable | getFrame(int index) | |
int | getNumberOfFrames() | |
void | inflate(Resources r, XmlPullParser parser, AttributeSet attrs) | 从XML文件中展开Drawable动画. |
boolean | isOneShot() | |
boolean | isRunning() | 返回动画是否还在运行. |
Drawable | mutate() | 继承自Drawable类.使drawable可变 |
void | run() | 可以在子类中重写,不要直接调用. |
void | setOneShot(boolean oneShot) | 设置运行一次还是重复运行. |
boolean | setVisible(boolean visible, boolean restart) | 设置是否可见. |
void | start() | 开始运行动画. |
void | stop() | 停止动画. |
void | unscheduleSelf(Runnable what) | Drawable.Callback 接口的实现. |
xml文件的使用
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/lighthouse"
android:duration="1000"/>
<item
android:drawable="@drawable/penguins"
android:duration="1000"/>
<item
android:drawable="@drawable/tulips"
android:duration="1000"/>
</animation-list>
在代码中使用xml文件,就如同使用drawable资源一样,既可以在xml文件中赋给ImageView作为背景,可以把它放在ImageView中通过代码作为背景。
然后通过ImageView的getBackground()得到这个Drawable。然后调用start() 方法开始运行动画.
这里通过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" >
<ImageView
android:id="@+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="300dp"
android:background="@drawable/drawableanim" />
<Button
android:id="@+id/button1"
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Anim" />
</LinearLayout>
java代码:
package com.example.scrolltest;
import android.app.Activity;
import android.graphics.drawable.AnimationDrawable;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
public class DrawableAnim extends Activity {
ImageView iv ;
Button bt;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.drawanimlayout);
iv=(ImageView)findViewById(R.id.imageView1);
bt=(Button)findViewById(R.id.button1);
final AnimationDrawable drawableAnim=(AnimationDrawable) iv.getBackground();
bt.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
drawableAnim.start();
}
});
}
}
效果图:
注意:
动画的开始start()方法不能够在onCreate()中调用,因为那时AnimationDrawable还没有attach到window。如果想Activity启动后调用,可以在 onWindowFocusChanged()方法里调用,这个时候界面获得了焦点,调用不会出错。
(我试了一下,但是并没有出错,也能正常运行动画,可能这个是不能够保证一定已经attach到window了)
硬编码
当XML无法满足需求的时候,可是使用代码来定义Drawable动画,比如Drawable资源不是预设好的,而是来自于网络,这时候可以通过代码来添加Drawable对象。
下面代码实现和上面XML方式同样效果的帧动画。
package com.example.scrolltest;
import android.app.Activity;
import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
public class DrawableAnim extends Activity {
ImageView iv ;
Button bt;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.drawanimlayout);
iv=(ImageView)findViewById(R.id.imageView1);
bt=(Button)findViewById(R.id.button1);
//final AnimationDrawable drawableAnim=(AnimationDrawable) iv.getBackground();
final AnimationDrawable drawableAnim=new AnimationDrawable();
Drawable drawable1=getResources().getDrawable(R.drawable.lighthouse);
Drawable drawable2=getResources().getDrawable(R.drawable.penguins);
Drawable drawable3=getResources().getDrawable(R.drawable.tulips);
drawableAnim.addFrame(drawable1, 1000);
drawableAnim.addFrame(drawable2, 1000);
drawableAnim.addFrame(drawable3, 1000);
drawableAnim.setOneShot(false);
iv.setBackground(drawableAnim);
bt.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
drawableAnim.start();
}
});
}
}
效果相同,不再加图。