AnimView Android帧动画

xiaoxiao2021-02-28  52

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(); } }
转载请注明原文地址: https://www.6miu.com/read-72776.html

最新回复(0)