public class GifView extendsView {/*** 默认为1秒*/
private static final int DEFAULT_MOVIE_DURATION = 1000;private intmMovieResourceId;privateMovie mMovie;private longmMovieStart;private int mCurrentAnimationTime = 0;private floatmLeft;private floatmTop;private floatmScale;private intmMeasuredMovieWidth;private intmMeasuredMovieHeight;private boolean mVisible = true;private volatile boolean mPaused = false;publicGifView(Context context) {this(context, null);
}publicGifView(Context context, AttributeSet attrs) {this(context, attrs, R.styleable.CustomTheme_gifViewStyle);
}public GifView(Context context, AttributeSet attrs, intdefStyle) {super(context, attrs, defStyle);
setViewAttributes(context, attrs, defStyle);
}
@SuppressLint("NewApi")private voidsetViewAttributes(Context context, AttributeSet attrs,intdefStyle) {if (Build.VERSION.SDK_INT >=Build.VERSION_CODES.HONEYCOMB) {
setLayerType(View.LAYER_TYPE_SOFTWARE,null);
}//从描述文件中读出gif的值,创建出Movie实例
final TypedArray array =context.obtainStyledAttributes(attrs,
R.styleable.GifView, defStyle, R.style.Widget_GifView);
mMovieResourceId= array.getResourceId(R.styleable.GifView_gif, -1);
mPaused= array.getBoolean(R.styleable.GifView_paused, false);
array.recycle();if (mMovieResourceId != -1) {
mMovie=Movie.decodeStream(getResources().openRawResource(
mMovieResourceId));
}
}/*** 设置gif图资源
*
*@parammovieResId*/
public void setMovieResource(intmovieResId) {this.mMovieResourceId =movieResId;
mMovie=Movie.decodeStream(getResources().openRawResource(
mMovieResourceId));
requestLayout();
}public voidsetMovie(Movie movie) {this.mMovie =movie;
requestLayout();
}publicMovie getMovie() {returnmMovie;
}public void setMovieTime(inttime) {
mCurrentAnimationTime=time;
invalidate();
}/*** 设置暂停
*
*@parampaused*/
public void setPaused(booleanpaused) {this.mPaused =paused;if (!paused) {
mMovieStart=android.os.SystemClock.uptimeMillis()-mCurrentAnimationTime;
}
invalidate();
}/*** 判断gif图是否停止了
*
*@return
*/
public booleanisPaused() {return this.mPaused;
}
@Overrideprotected void onMeasure(int widthMeasureSpec, intheightMeasureSpec) {if (mMovie != null) {int movieWidth =mMovie.width();int movieHeight =mMovie.height();int maximumWidth =MeasureSpec.getSize(widthMeasureSpec);float scaleW = (float) movieWidth / (float) maximumWidth;
mScale= 1f /scaleW;
mMeasuredMovieWidth=maximumWidth;
mMeasuredMovieHeight= (int) (movieHeight *mScale);
setMeasuredDimension(mMeasuredMovieWidth, mMeasuredMovieHeight);
}else{
setMeasuredDimension(getSuggestedMinimumWidth(),
getSuggestedMinimumHeight());
}
}
@Overrideprotected void onLayout(boolean changed, int l, int t, int r, intb) {super.onLayout(changed, l, t, r, b);
mLeft= (getWidth() - mMeasuredMovieWidth) /2f;
mTop= (getHeight() - mMeasuredMovieHeight) /2f;
mVisible= getVisibility() ==View.VISIBLE;
}
@Overrideprotected voidonDraw(Canvas canvas) {if (mMovie != null) {if (!mPaused) {
updateAnimationTime();
drawMovieFrame(canvas);
invalidateView();
}else{
drawMovieFrame(canvas);
}
}
}
@SuppressLint("NewApi")private voidinvalidateView() {if(mVisible) {if (Build.VERSION.SDK_INT >=Build.VERSION_CODES.JELLY_BEAN) {
postInvalidateOnAnimation();
}else{
invalidate();
}
}
}private voidupdateAnimationTime() {long now =android.os.SystemClock.uptimeMillis();//如果第一帧,记录起始时间
if (mMovieStart == 0) {
mMovieStart=now;
}//取出动画的时长
int dur =mMovie.duration();if (dur == 0) {
dur=DEFAULT_MOVIE_DURATION;
}//算出需要显示第几帧
mCurrentAnimationTime = (int) ((now - mMovieStart) %dur);
}private voiddrawMovieFrame(Canvas canvas) {//设置要显示的帧,绘制即可
mMovie.setTime(mCurrentAnimationTime);
canvas.save(Canvas.MATRIX_SAVE_FLAG);
canvas.scale(mScale, mScale);
mMovie.draw(canvas, mLeft/ mScale, mTop /mScale);
canvas.restore();
}
@SuppressLint("NewApi")
@Overridepublic void onScreenStateChanged(intscreenState) {super.onScreenStateChanged(screenState);
mVisible= screenState ==SCREEN_STATE_ON;
invalidateView();
}
@SuppressLint("NewApi")
@Overrideprotected void onVisibilityChanged(View changedView, intvisibility) {super.onVisibilityChanged(changedView, visibility);
mVisible= visibility ==View.VISIBLE;
invalidateView();
}
@Overrideprotected void onWindowVisibilityChanged(intvisibility) {super.onWindowVisibilityChanged(visibility);
mVisible= visibility ==View.VISIBLE;
invalidateView();
}