在Android中顯示GIF動畫

來源:互聯網
上載者:User

gif圖動畫在android中還是比較常用的,比如像新浪微博中,有很多gif圖片,而且展示非常好,所以我也想弄一個。經過我多方的搜尋資料和整理,終於弄出來了,其實github上有很多開源的gif的展示代碼,我下載過幾個,但是都不是很理想,不是我完全想要的。所以有時候就得自己學會總結,把開源的東西整理成自己的,現在無聊,也正好有朋友需要,所以現在整理了一下,留著以後備用!

廢話不多說,直接:


在這裡主要用的是:android中的android.graphics.Movie 這個類,這是android提供給我們的一個非常方便的工具。

首先,重寫控制項View,自訂一個展示gif圖的GifView,代碼如下:

package net.loonggg.gif.view;import net.loonggg.gif.R;import android.annotation.SuppressLint;import android.content.Context;import android.content.res.TypedArray;import android.graphics.Canvas;import android.graphics.Movie;import android.os.Build;import android.util.AttributeSet;import android.view.View;public class GifView extends View {/** * 預設為1秒 */private static final int DEFAULT_MOVIE_DURATION = 1000;private int mMovieResourceId;private Movie mMovie;private long mMovieStart;private int mCurrentAnimationTime = 0;private float mLeft;private float mTop;private float mScale;private int mMeasuredMovieWidth;private int mMeasuredMovieHeight;private boolean mVisible = true;private volatile boolean mPaused = false;public GifView(Context context) {this(context, null);}public GifView(Context context, AttributeSet attrs) {this(context, attrs, R.styleable.CustomTheme_gifViewStyle);}public GifView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);setViewAttributes(context, attrs, defStyle);}@SuppressLint("NewApi")private void setViewAttributes(Context context, AttributeSet attrs,int defStyle) {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圖資源 *  * @param movieResId */public void setMovieResource(int movieResId) {this.mMovieResourceId = movieResId;mMovie = Movie.decodeStream(getResources().openRawResource(mMovieResourceId));requestLayout();}public void setMovie(Movie movie) {this.mMovie = movie;requestLayout();}public Movie getMovie() {return mMovie;}public void setMovieTime(int time) {mCurrentAnimationTime = time;invalidate();}/** * 設定暫停 *  * @param paused */public void setPaused(boolean paused) {this.mPaused = paused;if (!paused) {mMovieStart = android.os.SystemClock.uptimeMillis()- mCurrentAnimationTime;}invalidate();}/** * 判斷gif圖是否停止了 *  * @return */public boolean isPaused() {return this.mPaused;}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {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, int b) {super.onLayout(changed, l, t, r, b);mLeft = (getWidth() - mMeasuredMovieWidth) / 2f;mTop = (getHeight() - mMeasuredMovieHeight) / 2f;mVisible = getVisibility() == View.VISIBLE;}@Overrideprotected void onDraw(Canvas canvas) {if (mMovie != null) {if (!mPaused) {updateAnimationTime();drawMovieFrame(canvas);invalidateView();} else {drawMovieFrame(canvas);}}}@SuppressLint("NewApi")private void invalidateView() {if (mVisible) {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {postInvalidateOnAnimation();} else {invalidate();}}}private void updateAnimationTime() {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 void drawMovieFrame(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(int screenState) {super.onScreenStateChanged(screenState);mVisible = screenState == SCREEN_STATE_ON;invalidateView();}@SuppressLint("NewApi")@Overrideprotected void onVisibilityChanged(View changedView, int visibility) {super.onVisibilityChanged(changedView, visibility);mVisible = visibility == View.VISIBLE;invalidateView();}@Overrideprotected void onWindowVisibilityChanged(int visibility) {super.onWindowVisibilityChanged(visibility);mVisible = visibility == View.VISIBLE;invalidateView();}}
Movie其實管理著GIF動畫中的多個幀,只需要通過 setTime() 一下就可以讓它在draw()的時候繪出相應的那幀映像。通過目前時間與duration之間的換算關係,是很容易實現GIF動起來的效果。

其次,在xml布局檔案中,把這個view定義進去,代碼如下:

        
最後,在MainActivity中的使用,代碼如下:

package net.loonggg.gif;import net.loonggg.gif.view.GifView;import android.app.Activity;import android.os.Bundle;public class Gif extends Activity {private GifView gif1, gif2;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);gif1 = (GifView) findViewById(R.id.gif1);// 設定背景gif圖片資源gif1.setMovieResource(R.raw.kitty);gif2 = (GifView) findViewById(R.id.gif2);gif2.setMovieResource(R.raw.b);// 設定暫停// gif2.setPaused(true);}}
注意:與ImageView和其他View唯一的區別在於我加了一個gif屬性。

                                        
這個代碼已經非常好了,使用也非常方便,其實不懂代碼是什麼意思也可以很好的用,只需要懂得我寫注釋的那幾行和Activity裡面的那幾行代碼就可以了!
轉載請註明出處:http://blog.csdn.net/loongggdroid/article/details/21166563

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.