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