这段时间事情比较多,更新可能不太及时,还请见谅。好了,不说废话了,

首先在values目录下新建一个attrs.xml的文件
<?xml version="1.0" encoding="utf-8"?>                        

AnimaImageView继承自ImageView,这个类必须支持ImageView的所有功能,这样咱们就可以通过这个类来完成咱们所需要的功能:

public class AnimaImageView extends ImageView implements View.OnClickListener {    /**     * 是否自动播放     */    private boolean isAutoPlay;    /**     * 播放GIF动画的关键类     */    private Movie mMovie;    /**     * gif宽高     */    private BitmapSize bitmapSize;    /**     * 播放按钮     */    private Bitmap mStartBotton;    /**     * 是否正在播放gif     */    private boolean isPlaying;    /**     * gif开始时间     */    private long mMovieStart;     public AnimaImageView(Context context) {        super(context);    }     public AnimaImageView(Context context, AttributeSet attrs) {        this(context, attrs,0);    }     public AnimaImageView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {            this.setLayerType(View.LAYER_TYPE_SOFTWARE,null);        }        obtainStyledAttr(context,attrs,defStyleAttr);    }     private void obtainStyledAttr(Context context, AttributeSet attrs, int defStyleAttr) {        TypedArray a=context.getTheme().obtainStyledAttributes(attrs,R.styleable.AnimaImageView,defStyleAttr,0);        int resId=getIdentifier(a);        if(resId!=0){            // 当资源id不等于0时,就去获取该资源的流            InputStream is=getResources().openRawResource(resId);            // 使用Movie类对流进行解码            mMovie=Movie.decodeStream(is);            //mMovie不等null说明这是一个GIF图片            if(mMovie!=null){                this.setLayerType(View.LAYER_TYPE_SOFTWARE,null);                //是否自动播放                isAutoPlay=a.getBoolean(R.styleable.AnimaImageView_auto_play,false);                /**                 * 获取gif图片大小                 */                Bitmap bitmap= BitmapFactory.decodeStream(is);                bitmapSize=new BitmapSize(bitmap.getWidth(),bitmap.getHeight());                bitmap.recycle();                if(!isAutoPlay){                    // 当不允许自动播放的时候,得到开始播放按钮的图片,并注册点击事件                    mStartBotton=BitmapFactory.decodeResource(getResources(),R.drawable.g1);                    setOnClickListener(this);                }            }        }        a.recycle();    }     @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        //当时gif图片的时候,控件宽高为gif文件大小        if(mMovie!=null){           setMeasuredDimension(bitmapSize.width,bitmapSize.height);        }    }     @Override    protected void onDraw(Canvas canvas) {        //当为一张普通的图片的时候        if(mMovie==null){            super.onDraw(canvas);        }else{            //如果自动播放的话,就直接播放            if(isAutoPlay){                playMovie(canvas);                invalidate();            }else{                //如果已经点击了播放按钮的话就开始播放gif                if(isPlaying){                    if(playMovie(canvas)){                        isPlaying=false;                    }                    invalidate();                }else{                    // 还没开始播放就只绘制GIF图片的第一帧,并绘制一个开始按钮                    mMovie.setTime(0);                    mMovie.draw(canvas, 0, 0);                    int offsetW = bitmapSize.width ;                    int offsetH = bitmapSize.height;                    canvas.drawBitmap(mStartBotton, offsetW, offsetH, null);                }            }        }    }    /**     * 开始播放GIF动画,播放完成返回true,未完成返回false。     *     * @param canvas     * @return 播放完成返回true,未完成返回false。     */    private boolean playMovie(Canvas canvas) {        //获取当前时间        long now = SystemClock.uptimeMillis();        if (mMovieStart == 0) {            mMovieStart = now;        }        int duration = mMovie.duration();        if (duration == 0) {            duration = 1000;        }        int relTime = (int) ((now - mMovieStart) % duration);        mMovie.setTime(relTime);//不断的设置gif的播放位置        mMovie.draw(canvas, 0, 0);//将movie画在canvas上        //如果(当前时间-gif开始的时间=gif总时长)说明播放完毕了        if ((now - mMovieStart) >= duration) {            mMovieStart = 0;            return true;        }        return false;    }    /**     * 通过反射获取src中的资源id     * @param a     */    private int getIdentifier(TypedArray a) {        try {            Field mValueFiled = a.getClass().getDeclaredField("mValue");            mValueFiled.setAccessible(true);            TypedValue typedValue= (TypedValue) mValueFiled.get(a);            return typedValue.resourceId;        } catch (NoSuchFieldException e) {            e.printStackTrace();        } catch (IllegalAccessException e) {            e.printStackTrace();        }        return 0;    }     /**     * 当点击图片的时候播放gif     */    @Override    public void onClick(View v) {        isPlaying = true;        invalidate();    }     /**     * BitmapSize     */    class BitmapSize{        private int width;        private int height;         public BitmapSize(int width, int height) {            this.width = width;            this.height = height;        }    }}

最后就是在想要的xml页面引用

这里要注意包名:com.shang.androidgif.AnimaImageView
attr:auto_play=“false” 是禁止fig动画自动播放。

可改为 attr:auto_play=“true” 自动播放。

有些4.0以上系统的手机启动了硬件加速功能之后会导致GIF动画播放不出来,因此我们需要在AndroidManifest.xml中去禁用硬件加速功能。

AndroidManifest.xml,在application 下增加

android:hardwareAccelerated="false" android:largeHeap="true"

如果src属性里面指定的是一张PNG图片,图片在布局正中央也会显示出来,正是普通ImageView所具备的功能。

最后的最后,请大家多多关注微信公众号:

Android ImageView播放gif遇到的坑_第1张图片

更多相关文章

  1. Android ImageView图片自适应大小
  2. 设置系统超时时间
  3. android切换到后台图片纹理丢失的解决方案
  4. 万能imageLoader加载图片的包装,直接用
  5. 2010.12.16——— android listView 显示图片 内存溢出问题
  6. [置顶] 我的Android进阶之旅------>android异步加载图片显示,并且
  7. 探讨android图片资源的抖动处理和格式转换
  8. 转载 Android 通过adb shell命令查看内存,CPU,启动时间,电量等信息
  9. Android之解决ViewPager2+PhotoView滑动图片花屏问题

随机推荐

  1. Android对国际化的支持
  2. WINDOWS7环境下android studio、NDK配置
  3. Android(安卓)10开启调试模式
  4. Android通过lame进行音频格式转换
  5. android开发――通过子线程更新界面UI
  6. Android视频播放项目总结之 使用第三方Vi
  7. Android(安卓)调用系统相机,拍照,并上传图
  8. android布局管理器使用方法
  9. android通过webview+jquery设计界面
  10. Android中动态调整ImageView的宽高比