1. 程式人生 > >能夠播放gif動畫的ImageView

能夠播放gif動畫的ImageView

ima data googl factor ida nal settime canvas off

一般ImageView並不能播放gif動畫。

此處播放gif動畫的核心是:

1.將gif中的每一幀拿出來,然後使用Movie類的setTime()和draw()這兩個方法來實時的畫界面。

2.在ondraw中來處理這些繪制操作。進行邏輯推斷,是否自己主動播放,假設不是自己主動播放的話就須要繪制一個開始button,同事設置畫面定位到gif動畫的第一幀


其它在代碼中查看。主要類GifImageView.java凝視比較全。應該看懂問題不大。

註意的是,須要values目錄下創建attrs,由於須要自己定義屬性auto_play


package com.pzf.gifaniamtion;

import java.io.InputStream;
import java.lang.reflect.Field;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Movie;
import android.os.SystemClock;
import android.text.method.MovementMethod;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageView;

/**
 * 播放動畫的主類
 * 
 * @author pangzf
 * @time 2014年10月14日 下午2:14:05
 */
public class GifImageView extends ImageView implements OnClickListener {
	
	private Movie mMovie;//播放動畫須要用到的。系統類
	private int mImageWidth;//動畫的imageview的寬度
	private int mImageHeight;//動畫imageview的高度
	private long mMovieStart = 0;// 播放開始
	private boolean isAutoPlay;//是否自己主動播放
	private Bitmap mStartPlay;//開始button
	private boolean isPlaying=false;//記錄是否正在播放

	public GifImageView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		init(context, attrs);
	}
	public GifImageView(Context context, AttributeSet attrs) {
		this(context, attrs, 0);
	}

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

	private void init(Context context, AttributeSet attrs) {
		TypedArray attributes = context.obtainStyledAttributes(attrs,
				R.styleable.GifImageView);
		// 拿資源id
		int resourceId = getResourceId(attributes, context, attrs);
		if (resourceId != 0) {
			// 說明是gif動畫
			// 1.將resourcesId變成流
			// 2.用Move來decode解析流
			// 3.獲得bitmap的長寬
			InputStream is = getResources().openRawResource(resourceId);
			mMovie = Movie.decodeStream(is);
			if (mMovie != null) {
				Bitmap bitmap = BitmapFactory.decodeStream(is);
				mImageWidth = bitmap.getWidth();
				mImageHeight = bitmap.getHeight();
				// 用完釋放
				bitmap.recycle();
				// 獲得是否同意自己主動播放,假設不同意自己主動播放。則初始化播放button
				isAutoPlay = attributes.getBoolean(
						R.styleable.GifImageView_auto_play, false);
				if (!isAutoPlay) {
					mStartPlay = BitmapFactory.decodeResource(getResources(),
							R.drawable.start_play);
					setOnClickListener(this);
				}
			}
		}
	}

	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
		if (mMovie != null) {
			// 假設是gif的話。設定大小
			setMeasuredDimension(mImageWidth, mImageHeight);
		}
	}

	@Override
	protected void onDraw(Canvas canvas) {
		if (mMovie == null) {
			// 普通的圖片
			super.onDraw(canvas);
		} else {
			if (isAutoPlay) {
				// 假設是gif動畫的話。就播放
				playMovie(canvas);
				invalidate();
			} else {
				// 不同意自己主動播放的話
				// 1.推斷是否正在播放
				// 2.獲得第一幀的圖像
				// 3.然後加入播放button
				if (isPlaying) {
					// 假設正在播放就playmoive繼續播放
					if (playMovie(canvas)) {
						isPlaying = false;
					}
					invalidate();
				} else {
					// 第一幀
					mMovie.setTime(0);
					mMovie.draw(canvas, 0, 0);
					// 繪制開始button
					int offsetW = (mImageWidth - mStartPlay.getWidth()) / 2;
					int offsetH = (mImageHeight - mStartPlay.getHeight()) / 2;
					canvas.drawBitmap(mStartPlay, offsetW, offsetH, null);
				}
			}

		}

	}

	/**
	 * 播放gif動畫
	 * 
	 * @param canvas
	 */
	private boolean playMovie(Canvas canvas) {
		// 1.獲取播放的時間
		// 2.假設開始start=0,則覺得是開始
		// 3.記錄播放的時間
		// 4.設置進度
		// 5.畫動畫
		// 6.假設時間大於了播放的時間,則證明結束
		long now = SystemClock.uptimeMillis();
		if (mMovieStart == 0) {
			mMovieStart = now;
		}
		int duration = mMovie.duration();
		if (duration == 0) {
			duration = 1000;
		}
		//記錄gif播放了多少時間
		int relTime = (int) ((now - mMovieStart) % duration);
		mMovie.setTime(relTime);// 設置時間
		mMovie.draw(canvas, 0, 0);// 畫
		if ((now - mMovieStart) >= duration) {
			// 結束
			mMovieStart = 0;
			return true;
		}
		return false;
	}



	/**
	 * 通過反射拿布局中src的資源id
	 * 
	 * @param attrs
	 * @param context
	 * @param attributes
	 */
	private int getResourceId(TypedArray attributes, Context context,
			AttributeSet attrs) {
		try {
			Field filed = TypedArray.class.getDeclaredField("mValue");
			filed.setAccessible(true);
			TypedValue typeValue = (TypedValue) filed.get(attributes);
			return typeValue.resourceId;
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (attributes != null) {
				attributes.recycle();
			}
		}
		return 0;
	}

	@Override
	public void onClick(View v) {
		if(v.getId()==getId()){
			isPlaying=true;
			invalidate();
		}
	}
}
attrs.xml
<?xml version="1.0" encoding="utf-8"?

> <resources> <declare-styleable name="GifImageView"> <attr name="auto_play" format="boolean"></attr> </declare-styleable> </resources>


布局文件

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:attr="http://schemas.android.com/apk/res/com.pzf.gifaniamtion"
    android:layout_width="match_parent"
    android:layout_height="match_parent" 
    android:gravity="center"
    >

    <com.pzf.gifaniamtion.GifImageView
        android:id="@+id/image_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/gif_animation" 
        attr:auto_play="false"
        />

</LinearLayout>

假設希望進入自己主動播放僅僅需將

 attr:auto_play="true"

效果圖:用的應用包手動截的手機的圖效果不好,有須要的能夠自己下載源代碼。那個流暢。

技術分享

源代碼地址:

點擊打開鏈接


個人項目txtreader:已經公布google play。http://blog.csdn.net/pangzaifei/article/details/52756777

有須要的能夠聯系


能夠播放gif動畫的ImageView