0
点赞
收藏
分享

微信扫一扫

Frame-by-Frame动画,有两种方法


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,

 
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 动画。

本节关键词:AnimationDrawable、BitmapDrawable、Bitmap、Frame Animation

Demo工程下载:

FrameAnimation.zip


举报

相关推荐

0 条评论