AnimView Android帧动画

public class AnimView extends View {

    private final String TAG = AnimView.class.getCanonicalName();

    private final int INVALIDATE = 0x0023;

    private HandlerThread thread;
    private Handler handler;

    private int width = 0;
    private int height = 0;

    private String animFilePath;
    private String[] animFileList;
    private int index;
    private int repeatIndex;
    private Bitmap bitmap;

    private String defaultPath;
    private String currentPath;

    private final Object lock = new Object();
    private boolean isRunning;
    private boolean isPrepare;

    private boolean isOneShot;
    private int time;

    private OnAnimationFinishListener listener;
    private Handler callbackHandler = new Handler(new Handler.Callback() {
        @Override
        public boolean handleMessage(Message msg) {
            switch (msg.what) {
                case INVALIDATE:
                    ViewGroup.LayoutParams layoutParams = getLayoutParams();
                    layoutParams.width = bitmap.getWidth();
                    layoutParams.height = bitmap.getHeight();
                    setLayoutParams(layoutParams);
                    break;
            }
            return false;
        }
    });

    public AnimView(Context context) {
        super(context);
    }

    public AnimView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public AnimView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    private void init() {
        repeatIndex = 0;
        isRunning = false;
        isOneShot = true;
        time = 83;
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        init();
        if (thread == null) {
            thread = new HandlerThread(TAG);
            thread.start();
            handler = new Handler(thread.getLooper());
        }

        synchronized (lock) {
            isPrepare = true;
            if (isRunning) {
                handler.post(animRunnable);
            } else if (defaultPath != null) {
                drawableDefault();
            }
        }
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        isPrepare = false;
        stop();
        handler.removeCallbacks(animRunnable);
    }

    public void setDefaultPath(String path) {
        defaultPath = path;
        drawableDefault();
    }

    private void drawableDefault() {
        currentPath = defaultPath;

        postInvalidate();
    }

    public void start(String path) {
        if (this.animFilePath == null || !this.animFilePath.equals(path)) {
            stop();
            this.animFilePath = path;
            animFileList = AssetsUtil.getAssetsFileList(getContext(), path);
            repeatIndex = 0;
        }

        synchronized (lock) {
            index = 0;
            if (isRunning == true) {
                return;
            }
            isRunning = true;
            if (isPrepare) {
                handler.removeCallbacks(animRunnable);
                handler.post(animRunnable);
            }
        }
    }

    public void stop() {
        synchronized (lock) {
            isRunning = false;
        }
    }

    public String getAnimFilePath() {
        return animFilePath;
    }

    public boolean isRunning() {
        return isRunning;
    }

    public void setOneShot(boolean oneShot) {
        this.isOneShot = oneShot;
    }

    public void setTime(int time) {
        this.time = time;
    }

    public void setRepeatIndex(int index) {
        repeatIndex = index;
    }

    public void setAnimationFinishListener(OnAnimationFinishListener listener) {
        this.listener = listener;
    }

    @Override
    protected void onDraw(Canvas c) {
        super.onDraw(c);
        if (bitmap != null) {
            if (!bitmap.isRecycled()) {
                bitmap.recycle();
            }
            bitmap = null;
        }
        if (c != null) {
            bitmap = AssetsUtil.readBitmapFromAssets(getContext(), currentPath, Bitmap.Config.ARGB_8888);
            c.drawBitmap(bitmap, 0, 0, null);
            if (bitmap != null) {
                if (width == 0 || height == 0
                        || width != bitmap.getWidth() || height != bitmap.getHeight()) {
                    Log.v(TAG, "call measure");
                    width = bitmap.getWidth();
                    height = bitmap.getHeight();
                    callbackHandler.sendEmptyMessage(INVALIDATE);
                }
            }
        }
    }

    Runnable animRunnable = new Runnable() {

        @Override
        public void run() {
            index = 0;
            while (true) {
                currentPath = animFileList[index];

                postInvalidate();

                try {
                    Thread.sleep(time);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

                synchronized (lock) {
                    index++;
                    if (index >= animFileList.length) {
                        if (!isOneShot) {
                            index = repeatIndex;
                        } else {
                            isRunning = false;
                            if (listener != null) {
                                listener.onAnimationFinish();
                            }
                            if (defaultPath != null) {
                                drawableDefault();
                            }
                            break;
                        }
                    }

                    if (!isRunning) {
                        break;
                    }
                }
            }
        }
    };

    public interface OnAnimationFinishListener {
        void onAnimationFinish();
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值