Android实现可播放GIF动画的ImageView

Android实现可播放GIF动画的ImageView,第1张

概述Android的原生控件并不支持播放GIF格式的图片。我们都知道,在Android中如果想要显示一张图片,可以借助ImageView来完成,但是如果将一张GIF图片设置到ImageView里,它只会显示这张图片的第一帧,不会产生任何的动画

AndroID的原生控件并不支持播放GIF格式的图片。我们都知道,在AndroID中如果想要显示一张图片,可以借助ImageVIEw来完成,但是如果将一张gif图片设置到ImageVIEw里,它只会显示这张图片的第一帧,不会产生任何的动画效果。今天我们来编写一个自定义的增强型ImageVIEw(继承ImageVIEw),可以播放GIF格式的图片,暂且叫做GifImageVIEw吧。

1.自定义属性

<?xml version="1.0" enCoding="utf-8"?> <resources>  <declare-styleable name="GifImageVIEw">   <attr name="auto_play" format="boolean"></attr>  </declare-styleable> </resources>

 2.自定义view中获取属性值

 private MovIE mMovIE;//播放动画需要用到的,系统类 private int mImageWIDth;//动画的imagevIEw的宽度 private int mImageHeight;//动画imagevIEw的高度 private long mMovIEStart = 0;// 播放开始 private boolean isAutoplay;//是否自动播放 private Bitmap mStartPlay;//开始按钮 private boolean isPlaying=false;//记录是否正在播放 private float mScale;//图片的缩放比 private int mMeasuredGifWIDth;//缩放后图片宽 private int mMeasuredGifheight;//缩放后图片高 ... private voID init(Context context,AttributeSet attrs) { TypedArray attributes = context.obtainStyledAttributes(attrs,R.styleable.GifImageVIEw); // 通过反射拿布局中src的资源ID,所以gif文件需要放在布局的src中 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();  // 获得是否允许自动播放,如果不允许自动播放,则初始化播放按钮  isAutoplay = attributes.getBoolean(R.styleable.GifImageVIEw_auto_play,false);  if (!isAutoplay) {   mStartPlay = BitmapFactory.decodeResource(getResources(),R.drawable.start_play);   setonClickListener(this);  }    } } //回收资源 attributes.recycle(); } /** * 通过反射拿布局中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(); } } return 0;}

3.重写onMesure()

 @OverrIDe protected voID onMeasure(int wIDthMeasureSpec,int heightmeasureSpec) { super.onMeasure(wIDthMeasureSpec,heightmeasureSpec); if (mMovIE != null) {  /*   * Calculate horizontal scaling   */  float scaleW = 1f;  int measureModeWIDth = MeasureSpec.getMode(wIDthMeasureSpec);  if (measureModeWIDth != MeasureSpec.UnspecIFIED) {   int maximumWIDth = MeasureSpec.getSize(wIDthMeasureSpec);   scaleW = (float) mImageWIDth / (float) maximumWIDth;  }  /*   * calculate vertical scaling   */  float scaleH = 1f;  int measureModeHeight = MeasureSpec.getMode(heightmeasureSpec);  if (measureModeHeight != MeasureSpec.UnspecIFIED) {   int maximumHeight = MeasureSpec.getSize(heightmeasureSpec);   scaleH = (float) mImageHeight / (float) maximumHeight;  }  /*   * calculate overall scale   */  mScale = 1f / Math.max(scaleH,scaleW);  mMeasuredGifWIDth = (int) (mImageWIDth * mScale);  mMeasuredGifheight = (int) (mImageHeight * mScale);  setMeasuredDimension(mMeasuredGifWIDth,mMeasuredGifheight); } }

4.重写onDraw()

 @OverrIDe protected voID onDraw(Canvas canvas) { if (mMovIE == null) {  // mMovIE等于null,说明是张普通的图片,则直接调用父类的onDraw()方法  super.onDraw(canvas); } else {  // mMovIE不等于null,说明是张gif图片  if (isAutoplay) {  // 如果允许自动播放,就播放  playMovIE(canvas);  invalIDate();  } else {  // 不允许自动播放的话  // 1.判断是否正在播放  // 2.获得第一帧的图像  // 3.然后添加播放按钮  if (isPlaying) {   // 如果正在播放就playmoive继续播放   if (playMovIE(canvas)) {   isPlaying = false;   }   invalIDate();  } else {   // 第一帧   mMovIE.setTime(0);   canvas.save(Canvas.MATRIX_SAVE_FLAG);   canvas.scale(mScale,mScale);   mMovIE.draw(canvas,0);// 画   canvas.restore();   // 绘制开始按钮   int offsetW = (mMeasuredGifWIDth - mStartPlay.getWIDth()) / 2;   int offsetH = (mMeasuredGifheight - 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);// 设置时间 canvas.save(Canvas.MATRIX_SAVE_FLAG); canvas.scale(mScale,mScale); mMovIE.draw(canvas,0);// 画 canvas.restore(); if ((Now - mMovIEStart) >= duration) {  // 结束  mMovIEStart = 0;  return true; } return false; }

5.添加点击事件

 @OverrIDe public voID onClick(VIEw v) { if(v.getID()==getID()){  isPlaying=true;  invalIDate(); } }

还有一点需要注意,有些4.0以上系统的手机启动了硬件加速功能之后会导致GIF动画播放不出来,因此我们需要在AndroIDManifest.xml中去禁用硬件加速功能,可以通过指定androID:harDWareAccelerated=false来完成。

--------------------------------------------------------------------------------

现在我们来看看运行后效果如何吧,
布局文件:

<linearLayout xmlns:androID="http://schemas.androID.com/apk/res/androID" xmlns:tools="http://schemas.androID.com/tools" xmlns:attr="http://schemas.androID.com/apk/res/com.hx.gifimagevIEw" androID:ID="@+ID/container" androID:layout_wIDth="match_parent" androID:layout_height="match_parent" androID:orIEntation="vertical" > <com.hx.gifimagevIEw.GifImageVIEw  androID:layout_wIDth="150dip"  androID:layout_height="150dip"  androID:layout_margin="10dp"  androID:src="@drawable/shulan"  attr:auto_play="false" /> <com.hx.gifimagevIEw.GifImageVIEw  androID:layout_wIDth="150dip"  androID:layout_height="150dip"  androID:layout_margin="10dp"  androID:src="@drawable/shulan"  attr:auto_play="true" /> <com.hx.gifimagevIEw.GifImageVIEw  androID:layout_wIDth="150dip"  androID:layout_height="150dip"  androID:layout_margin="10dp"  androID:src="@drawable/jingtai"  attr:auto_play="true" /></linearLayout>

 


图一的auto_play属性为false,会显示第一帧和一个播放按钮,点击后gif图片会自动运行。
图二的auto_play属性为true,会自动循环播放Gif。
图三我们给的资源是静态图片,因为自定义view继承ImageVIEw,所以具备ImageVIEw所有特性,因此也能显示静态图片。

源码下载:http://xiazai.jb51.net/201609/yuanma/GifImageView(jb51.net).rar

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程小技巧。

总结

以上是内存溢出为你收集整理的Android实现可播放GIF动画的ImageView全部内容,希望文章能够帮你解决Android实现可播放GIF动画的ImageView所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1148288.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-31
下一篇 2022-05-31

发表评论

登录后才能评论

评论列表(0条)

保存