自定义ImageView实现播放帧动画

来源:互联网 发布:java把字符串转为整形 编辑:程序博客网 时间:2024/06/08 10:16

对于帧动画的显示有多种不同的实现方式,帧动画的图片有两种不同的情形,一种是多个单张图片,放在animation-list对应的xml里面,采用轮播的方式进行;另一种是一张大图片排列不同的小图片,之前实现的方式是采用继承SurfaceView,另开线程,逐步分割图片显示,同样也是轮播的方式实现动画,现在我们综合以上两种实现方式,自定义自己实现一张大图的帧动画播放(ps:有时候为了便于维护,需要一张大图实现的帧动画,而不是多张小图片)
图片资源如下:

资源图片

播放简单可爱的图片来展示效果;
关键代码,自定义的ImageView:

package com.example.animationtest;import android.content.Context;import android.content.res.TypedArray;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.drawable.BitmapDrawable;import android.graphics.drawable.Drawable;import android.util.AttributeSet;import android.view.View;import android.widget.ImageView;/** * 自定义ImageView * @author xutao * */public class AnimationControl extends ImageView{    private Bitmap resourceBip; //播放的图片资源    private int duration; //时间间隔    private boolean positive; //正向还是反向播放    private int repeatCount; //重复播放的次数;0、循环    private int playAfter; //播放之后的动作    private MyAnimationDrawable animationDrawable; //播放的资源集合    public AnimationControl(Context context, AttributeSet attrs) {        super(context, attrs);        // TODO Auto-generated constructor stub        TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.animationView);        int resId = array.getResourceId(R.styleable.animationView_img, 0);        resourceBip = BitmapFactory.decodeResource(context.getResources(), resId);        duration = array.getInt(R.styleable.animationView_duration, 500);        positive = array.getBoolean(R.styleable.animationView_positive, true);        repeatCount = array.getInt(R.styleable.animationView_repeat_count, 0);        playAfter = array.getInt(R.styleable.animationView_play_after, 0);        int column = array.getInt(R.styleable.animationView_column_number, 1);        int row = array.getInt(R.styleable.animationView_row_number, 1);        array.recycle();        animationDrawable = new MyAnimationDrawable();        initAnimation(column, row);    }    public void initAnimation(int column, int row) {        int w = resourceBip.getWidth()/column;        int h = resourceBip.getHeight()/row;        if(positive) {            for (int i = 0; i < row; i++) {                int y = h*i;                for (int j = 0; j < column; j++) {                    int x = w*j;                    Drawable drawable = new BitmapDrawable(getResources(), Bitmap.createBitmap(resourceBip, x, y, w, h));                    animationDrawable.addFrame(drawable, duration);                }            }        } else {            for (int i = row-1; i >= 0; i--) {                int y = h*i;                for (int j = column-1; j >= 0; j--) {                    int x = w*j;                    Drawable drawable = new BitmapDrawable(getResources(), Bitmap.createBitmap(resourceBip, x, y, w, h));                    animationDrawable.addFrame(drawable, duration);                }            }        }        setImageDrawable(animationDrawable);        animationDrawable.setOneShot(false);        animationDrawable.setRepeatCount(repeatCount);        animationDrawable.setAnimationEndListener(new MyAnimationDrawable.AnimationEndListener() {            @Override            public void onEnd() {                // TODO Auto-generated method stub                switch (playAfter) {                case 0:                    break;                case 1:                    setVisibility(View.INVISIBLE);                    break;                case 2:                    setVisibility(View.GONE);                    break;                default:                    break;                }            }        });        animationDrawable.start();    }    public Drawable getCurrentDrawable() {        return animationDrawable.getCurrent();    }    public Drawable getIndexDrawable(int index) {        return animationDrawable.getFrame(index);    }}

由于自定义了styleable,所以附上attr.xml代码,该代码放在value文件夹下:

<?xml version="1.0" encoding="utf-8"?><resources>    <declare-styleable name="animationView">        <!-- 要播放的图片资源 -->        <attr name="img" format="reference" />        <!-- 播放时间间隔 -->        <attr name="duration" format="integer" />        <!-- 图片行数 -->        <attr name="row_number" format="integer" />        <!-- 图片列数 -->        <attr name="column_number" format="integer" />        <!-- ture为正向播放图片,false为反向播放图片 -->        <attr name="positive" format="boolean" />        <!-- 小于等于0为循环播放 -->        <attr name="repeat_count" format="integer" />        <!-- 非循环播放之后的响应;无效果 、不可见、隐藏-->        <attr name="play_after">            <flag name="visible" value="0" />            <flag name="invisible" value="1" />            <flag name="gone" value="2" />        </attr>    </declare-styleable></resources>

由于系统自带的AnimationDrawable不具有播放次数和播放结束的监听事件的功能,因此需要自定义AnimationDrawable,代码如下:

package com.example.animationtest;import android.graphics.drawable.AnimationDrawable;/** * 自定义AnimationDrawable * 实现播放次数控制和播放结束回调事件 *  * @author xutao * */public class MyAnimationDrawable extends AnimationDrawable {    private int repeatCount = 0;    private boolean isRepeat = true;    private AnimationEndListener listener;    public MyAnimationDrawable() {        super();    }    @Override    public void run() {        // TODO Auto-generated method stub        super.run();        if(!isRepeat) {            repeatCount --;            if(repeatCount == 1) {                super.unscheduleSelf(this);                if(listener != null) listener.onEnd();            }        }    }    public void setRepeatCount(int num) {        if(num == 0) isRepeat = true;        else {            isRepeat = false;            repeatCount = num*getNumberOfFrames();        }    }    public void setAnimationEndListener(AnimationEndListener ls) {        listener = ls;    }    /**     * 动画播放结束回调接口     * @author user     *     */    public interface AnimationEndListener {        public void onEnd();    }}

基本代码就是这些,对了,还有布局文件代码:

    <com.example.animationtest.AnimationControl        android:id="@+id/main_control"        android:layout_width="100dp"        android:layout_height="100dp"         animation:column_number="7"        animation:duration="100"        animation:img="@drawable/day"        animation:play_after="invisible"        animation:positive="true"        animation:repeat_count="8"        animation:row_number="1" />

好了,就是这些代码了,封装之后感觉好简单啊,相对于SurfaceView而言,不用另开线程,实现更加方便了!!!

DEMO下载地址 ^-^

1 0
原创粉丝点击