Android學習之ImageView放置gif動態圖

最近做圖片的時候碰到一個問題,就是imageview控件中放動態圖,顯示出來的效果跟靜態圖是一樣的。於是我網上大概找了一下資料,對於這方面大概有三個解決方法
一、將gif用工具分割,一幀一幀的播放

這篇博客中有介紹http://www.cnblogs.com/TerryBlog/archive/2010/09/06/1819641.html

二、使用開源框架

Glide是個不錯的選擇,當然也還有其他的,下面這篇博客,對於Glide講的還比較清晰
http://blog.csdn.net/fancylovejava/article/details/44747759

三、自定義imageview,使用Movie來播放

好了,對於這個,我親手做了個demo,註解還算全
由於是要自定義控件,我們還可能會用到一些自定義的屬性,因此在values目錄下新建一個attrs.xml的文件,可以在這個文件中添加任何需要自定義的屬性。這裏我們目前只需要一個auto_play屬性,代碼如下所示:
<declare-styleable name="MyImageView">
        <attr name="auto_play" format="boolean">

        </attr>
    </declare-styleable>

這個寫好了,接下來我們要寫一個類來繼承imageview或view

package com.jp.tools;

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.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.View;
import android.widget.ImageView;

import com.jp.activity.R;

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

/**
 * Created by Administrator on 2015/8/21.
 */
public class MyImageView extends ImageView implements View.OnClickListener
{


    /**
     * 播放GIF動畫的關鍵類
     */
    private Movie mMovie;
    /**
     * 控制播放的按鈕
     */
    private Bitmap mStartButton;

    /**
     * 記錄動畫開始的時間
     */
    private long mMovieStart;

    /**
     * GIF圖片的寬度
     */
    private int mImageWidth;

    /**
     * GIF圖片的高度
     */
    private int mImageHeight;

    /**
     * 圖片是否正在播放
     */
    private boolean isPlaying;

    /**
     * 是否允許自動播放
     */
    private boolean isAutoPlay;

    public MyImageView(Context context)
    {
        super(context);
        Log.e("ten", "72");
    }

    public MyImageView(Context context, AttributeSet attrs)
    {
        this(context, attrs, 0);
        Log.e("ten", "73");
    }

    public MyImageView(Context context, AttributeSet attrs, int defStyleAttr)
    {
        super(context, attrs, defStyleAttr);

        setImageResLoad(context, attrs, defStyleAttr);



    }

    private void setImageResLoad(Context context, AttributeSet attrs, int defStyleAttr)
    {
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.MyImageView);
        Log.e("ten", "1 ");
        int resourceID = getResourcesID(typedArray);
        typedArray.recycle();
        if (resourceID != 0) {
            Log.e("ten", "2 ");

            InputStream inputStream = getResources().openRawResource(resourceID);

            //對圖片進行解碼
            mMovie = Movie.decodeStream(inputStream);
            if (mMovie != null) {
                Log.e("ten", "3 ");
                // 如果返回值不等於null,就說明這是一個GIF圖片,下面獲取是否自動播放的屬性
                isAutoPlay = typedArray.getBoolean(R.styleable.MyImageView_auto_play, false);
                Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
                mImageWidth = bitmap.getWidth();
                mImageHeight = bitmap.getHeight();
                bitmap.recycle();
                if (!isAutoPlay) {
                    // 當不允許自動播放的時候,得到開始播放按鈕的圖片,並註冊點擊事件
                    mStartButton = BitmapFactory.decodeResource(getResources(),
                            R.drawable.ic_launcher);
                    setOnClickListener(this);
                }
            }

        }
    }

    /**
     * 通過Java反射,獲取src指定圖片資源所對應的id。
     */
    public int getResourcesID(TypedArray typedArray)
    {
        Log.e("ten", "4 ");
        try {
            Field field = TypedArray.class.getDeclaredField("mValue");
            field.setAccessible(true);
            TypedValue typedValueObject = (TypedValue) field.get(typedArray);
            return typedValueObject.resourceId;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (typedArray != null) {
                typedArray.recycle();
            }
        }
        return 0;
    }


    @Override
    public void onClick(View v)
    {
        Log.e("ten", "5 ");
        if (v.getId() == getId()) {
            //點擊圖片開始播放
            isPlaying = true;
            invalidate();
        }
    }

    @Override
    protected void onDraw(Canvas canvas)
    {
        Log.e("ten", "6");
        if (mMovie == null) {
            Log.e("ten", "7b");
            // mMovie等於null,說明是張普通的圖片,則直接調用父類的onDraw()方法
            super.onDraw(canvas);

        } else {
            Log.e("ten", "7c");
            //如果mMovie不等於null,那就說明是gif圖片
            if (isAutoPlay) {
                Log.e("ten", "7d");
                //如果允許播放,調用palyMovie();
                playMovie(canvas);
                invalidate();
            } else {
                Log.e("ten", "7e");
                //不允許自動播放,判斷是否要播放
                if (isPlaying) {
                    if (playMovie(canvas)) {
                        isPlaying = false;
                        Log.e("ten", "7f");
                    }
                    invalidate();
                } else {
                    // 還沒開始播放就只繪製GIF圖片的第一幀,並繪製一個開始按鈕
                    Log.e("ten", "g");
                    mMovie.setTime(0);
                    mMovie.draw(canvas, 0, 0);
                    int imageX = (mImageWidth - mStartButton.getWidth()) / 2;
                    int imageY = (mImageHeight - mStartButton.getHeight()) / 2;
                    canvas.drawBitmap(mStartButton, imageX, imageY, null);

                }
            }
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
    {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        Log.e("ten", "onMeasure_1");
        if (mMovie != null) {
            Log.e("ten", "onMeasure_2");
            // 如果是GIF圖片則重寫設定myImageView的大小
            setMeasuredDimension(mImageWidth, mImageHeight);
        }
    }
 /**  
     * 開始播放GIF動畫,播放完成返回true,未完成返回false。  
     *   
     * @param canvas  
     * @return 播放完成返回true,未完成返回false。  
     */ 
    public boolean playMovie(Canvas canvas)
    {
        Log.e("ten", "playMovie_1");
        long now = SystemClock.uptimeMillis();
        if (mMovieStart == 0) {
            mMovieStart = now;
        }
        int duration = mMovie.duration();
        if (duration == 0) {
            duration = 1000;
        }
        int loadTime = (int) ((now - mMovieStart) % duration);
        mMovie.setTime(loadTime);
        mMovie.draw(canvas, 0, 0);
        if ((now - mMovieStart) >= duration) {
            mMovieStart = 0;
            return true;
        }
        return false;
    }
}

佈局的代碼:

<com.jp.tools.MyImageView

        android:src="@drawable/pic_four"
        android:layout_width="match_parent"
        android:layout_height="match_parent"

        attr:auto_play="true"
        />
    <!--設置attr:auto_play="true"動態圖就會自動播放,如果不設置,或未false圖片就需要點了之後才播放 -->

效果圖(哈哈,還是很萌的妹紙吧):
這裏寫圖片描述
對了,還有一點需要說一下,這種方法的實現當gif圖片過大的時候會報oom。所以對於圖片的大小要注意一下。

希望大家多多交流,有什麼更好的實現方法

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章