转自:http://blog.longapps.com/archives/960
Frame帧动画通俗的说就是像放电影那样一帧一帧的连续播放出来。Frame帧动画主要是通过AnimationDrawable类来实现的,它有start()和stop()两个重要的方法来启动和停止动画。
一、一个动画序列图的实现,即Frame-by-Frame动画,有两种方法:
1、animation-list配置,预先将一个动画按照每帧分解成的多个图片所组成的序列。然后再在Android的配置文件中将这些图片配置到动画里面。不过这种方式通常是不推荐的,因为这会导致一大堆分割后的图片出现。
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false">
<item android:drawable="@drawable/explode1" android:duration="50" />
<item android:drawable="@drawable/explode2" android:duration="50" />
<item android:drawable="@drawable/explode3" android:duration="50" />
<item android:drawable="@drawable/explode4" android:duration="50" />
</animation-list>
2、AnimationDrawable动画。将同一动画序列的每帧图片都合并到一个大的图片中去,然后读取图片的时候按照约定好的宽、高去读就能准确的将该帧图片精确的读出来了。下图是星星闪烁序列图。
现在以第二种举例说明Frame Animation的用法。
二、Demo演示
1、新建一个工程后,将上面的星星序列图和下面的星星爆炸图放入工程。
2、在布局文件中,这里是main.xml加入两个imageView
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello" />
<ImageView
android:layout_height="35dip"
android:layout_width="35dip"
android:id="@+id/testImage"></ImageView>
<ImageView
android:src="@drawable/icon"
android:id="@+id/imageView12"
android:layout_height="90dip"
android:layout_width="90dip"></ImageView>
</LinearLayout>
3、使用AnimationDrawable来实现动画
这里要用到图片切割,所以会用到BitmapDrawable来获取一个Bitmap,
Resources res=getResources();
BitmapDrawable bmpDraw=(BitmapDrawable)res.getDrawable(R.drawable.vanishing_magiccube);
然后通过getBitmap获取一个Bitmap。
得到这个星星序列图之后,如何分割呢:
for (int frame = 0; frame < 5; frame++) {
Bitmap bitmap = Bitmap.createBitmap(bmp,
frame*90,
0,
90,
90);
animationDrawable2.addFrame(new BitmapDrawable(bitmap),120);
}
Bitmap的createBitmap方法,可以实现图片切割功能,具体请参考文档,这里星星序列图由5个小图组成,所以循环截取5个图片,然后将截取后的图片一个一个的放入animationDrawable中,间隔时间为120毫秒。
private void startFrameAnimation1(){
animationDrawable = new AnimationDrawable();
Bitmap[] bitmaps = new Bitmap[3];
//从资源文件中获取图片资源
Resources res=getResources();
BitmapDrawable bmpDraw=(BitmapDrawable)res.getDrawable(R.drawable.power_light_star2);
Bitmap bmp=bmpDraw.getBitmap();
for (int frame = 0; frame < bitmaps.length; frame++) {
Bitmap bitmap = Bitmap.createBitmap(bmp,
frame*35,
0,
35,
35);
animationDrawable.addFrame(new BitmapDrawable(bitmap),80);
}// for,每层有 PLAYER_XIAOXUE_WALK_FRAME 帧
//Sets whether the animation should play once or repeat.
animationDrawable.setOneShot(false);
ImageView starImg = (ImageView)findViewById(R.id.testImage);
starImg.setImageDrawable(animationDrawable);
// run the start() method later on the UI thread
//注意这里,因为是在onCreate()这个方法里加载了setImageDrawable,还没延迟,
//如果直接使用animationDrawable.start();是不会有任何效果的。
//所以,如果要在这里调用,必须使用post致一个Runnable那里,或者
//在onWindowFocusChanged实现,因为这个时候,已经获取了图片。
starImg.post(new Starter());
}
这里需要注意的是,不能在onCreate中直接调用animationDrawable的start方法。
有两种方法来解决这个animationDrawable不工作的问题。
第一个是使用post,让Runnable来启动start,第二个是使用onWindowFocusChange来启动start。Demo演示中使用了两种方法来分别启动frame 动画。