Android onDraw觸發ImageView的setImageBitmap實現動畫,可見時執行動畫,不可見時自動中止動畫

Android onDraw觸發ImageView的setImageBitmap實現動畫,可見時執行動畫,不可見時自動中止動畫
一個簡單的小例子,這個例子首先從assets讀取出若干張圖片做爲Bitmap資源,而後在onDraw裏面每一個25ms觸發一次ImageView的setImageBitmap,這樣作以25ms做爲週期,循環的每隔25ms從新設置ImageView的圖片源,達到動畫效果,這樣作的好處是,因爲onDraw只在可見狀態下重繪才調用,若是當前的自定義的ImageView不可見,自動就中止執行動畫,比較節能。java

package zhangphil.test;
 
import android.content.Context;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.Nullable;
import android.support.v7.widget.AppCompatImageView;
import android.util.AttributeSet;
import android.util.Log;
 
import java.io.InputStream;
 
public class LoadingImageView extends AppCompatImageView {
    private String TAG = "加載動畫";
    private Context mContext;
    private Bitmap[] mBitmaps;
 
    private int i = 0;
    private int WHAT = 0xfc01;
 
    /**
     * 是否執行動畫,若是爲false,不須要動畫邏輯。
     * 默認true執行。
     */
    private boolean mAnimationEnable = true;
 
    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            if (msg.what == WHAT) {
                mHandler.removeMessages(WHAT);
 
                //Log.d(TAG, "設置新動畫圖片");
                setImageBitmap(mBitmaps[i++ % mBitmaps.length]);
            }
        }
    };
 
    public LoadingImageView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
 
        mContext = context;
        init();
    }
 
    /**
     * true,當該View可見狀態下就執行動畫。
     * false,當前View不管處於何種狀態都不執行動畫。
     *
     * @param enable
     */
    public void setAnimationEnable(boolean enable) {
        mAnimationEnable = enable;
    }
 
    private void init() {
        mBitmaps = getBimaps();
        if (!isResOk()) {
            Log.e(TAG, "動畫資源爲空!");
            return;
        }
    }
 
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //Log.d(TAG, "onDraw");
 
        if (mAnimationEnable && isResOk()) {
            mHandler.sendEmptyMessageDelayed(WHAT, 25);
        }
    }
 
    private boolean isResOk() {
        return mBitmaps != null && mBitmaps.length > 0;
    }
 
    /**
     * 從assets目錄下讀取圖片資源放到數組裏面,做爲連續動畫的資源圖。
     *
     * @return
     */
    private Bitmap[] getBimaps() {
        final String parentPath = "loading";
 
        Bitmap[] bitmaps = null;
        AssetManager am = mContext.getAssets();
        try {
            String[] files = am.list(parentPath);
            bitmaps = new Bitmap[files.length];
            for (int i = 0; i < files.length; i++) {
                InputStream is = am.open(parentPath + "/" + files[i]);
                bitmaps[i] = BitmapFactory.decodeStream(is);
                is.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
 
        return bitmaps;
    }
}
使用方法和普通的ImageView同樣,這個自定義LoadingImageView比較適合下拉刷新時候頭部的滾動圓球動畫製做和實現。android

出於兼容高版本的目的,在上層Java代碼主動調用一次動畫的start方法觸發動畫:canvas

        ImageView mImageView = findViewById(R.id.load_image);
        AnimationDrawable mAnimationDrawable = (AnimationDrawable) mImageView.getDrawable();
        mAnimationDrawable.start();
由於代碼須要從assets目錄下的loading目錄下讀取圖片做爲動畫素材,所以須要事先在項目的assets目錄下放置一系列要連續加載的圖片。數組


————————————————
版權聲明:本文爲CSDN博主「zhangphil」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處連接及本聲明。
原文連接:https://blog.csdn.net/zhangphil/article/details/81980357ide

相關文章
相關標籤/搜索