Android自定义控件:动画类---逐帧动画AnimationDrawable

1:概述

            Android动画包括View Animation(视图动画)Property Animator(属性动画),而View Animation包括Tween Animation(补间动画)和Frame Animation(逐帧动画);补间动画主Animation(ScaleAnimation、 AlphaAnimation、RotateAnimation、TranslateAnimation)为主,而逐帧动画则是以AnimationDrawable为主。

2:定义逐帧动画

定义逐帧动画非常简单,只要在<animation-list.../>中使用<item.../>子元素定义动画的全部帧,并指定各帧的持续时间即可
<?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/scenery1"
    android:duration="1000"/>
 <item
        android:drawable="@drawable/scenery2"
        android:duration="1000"
        />
    <item
        android:drawable="@drawable/scenery3"
        android:duration="1000"
        />
    <item
        android:drawable="@drawable/scenery4"
        android:duration="1000"
        />
    <item
        android:drawable="@drawable/scenery5"
        android:duration="1000"
        />
</animation-list>
上面语法格式中android:onshot控制该动画是否循环播放,如果该参数指定为true,则动画将不会循环播放;否则该动画将会循环播放。每个<item.../>子元素增加一帧。
接下来就可用ImageView把AnimationDrawable显示出来,习惯上把AnimationDrawable设成ImageView的背景即可。
需要指出的是:AnimationDrawable代表的动画默认是不播放的,必须在程序中启动动画播放才可以。AnimationDrawable提供如下两个方法开始、停止动画。
 1> start():开始播放动画
 2> stop(): 停止播放动画

3:添加的帧数过多产生OOM的解决

<span style="font-size:18px;">private void loadBitmap(){
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inPurgeable=true;
        options.inInputShareable=true;
        //设置该属性可获得图片的长宽等信息,但是避免了不必要的提前加载动画
        options.inJustDecodeBounds=false;
        InputStream is=null;
        int[] raw={
                R.raw.scenery1,R.raw.scenery2,R.raw.scenery3,R.raw.scenery4,R.raw.scenery5
        };
        Bitmap[] mbitMap=new Bitmap[5];
        for(int i=0,j=0;i<5&&j<5;i++,j++){
            is=getResources().openRawResource(raw[i]);
            Bitmap bitmap =BitmapFactory.decodeStream(is, null, options);
            mbitMap[j]=bitmap;
        }

        AnimationDrawable clipDrawable= new AnimationDrawable();
        for(int i=0;i<5;i++){
            clipDrawable.addFrame(new BitmapDrawable(mbitMap[i]), 50);
        }
        clipDrawable.setOneShot(false);
        animationDrawable=clipDrawable;
        iv_frame.setBackground(animationDrawable);
    }</span>
setbackgroundResource()这种方法在设置animationDrawable动画的时候,是会在java层和native层产生两个实例的,而高像素bitmap图是特别占内存的,所以容易产生内存溢出问题,而我找到的最好解决方法是,不适用setBackgroundResource()这个方法而是首先使用decodeStream()这个方法读入bitmap字节码的流,而这个方法与decodeResource等其他方法相比,最好的地方在于它仅仅在native层也就是底层产生一个实例,但不会在java层使用createBitMap()方法产生实例,因此极大地减少了内存的占用,否则当读入20多张大图的时候很容易内存溢出。
posted @ 2016-07-14 14:09  vegatate  阅读(442)  评论(0编辑  收藏  举报