返回顶部
首页 > 资讯 > 移动开发 >Android实现可播放GIF动画的ImageView
  • 228
分享到

Android实现可播放GIF动画的ImageView

gif动画Android 2022-06-06 07:06:50 228人浏览 八月长安
摘要

Android的原生控件并不支持播放GIF格式的图片。我们都知道,在Android中如果想要显示一张图片,可以借助ImageView来完成,但是如果将一张GIF图片设置到Ima

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();
 }
 
 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) {
  
  float scaleW = 1f;
  int measureModeWidth = MeasureSpec.getMode(widthMeasureSpec);
  if (measureModeWidth != MeasureSpec.UNSPECIFIED) {
   int maximumWidth = MeasureSpec.getSize(widthMeasureSpec);
   scaleW = (float) mImageWidth / (float) maximumWidth;
  }
  
  float scaleH = 1f;
  int measureModeHeight = MeasureSpec.getMode(heightMeasureSpec);
  if (measureModeHeight != MeasureSpec.UNSPECIFIED) {
   int maximumHeight = MeasureSpec.getSize(heightMeasureSpec);
   scaleH = (float) mImageHeight / (float) maximumHeight;
  }
  
  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, 0);// 画
   canvas.restore();
   // 绘制开始按钮
   int offsetW = (mMeasuredGifWidth - mStartPlay.getWidth()) / 2;
   int offsetH = (mMeasuredGifHeight - mStartPlay.getHeight()) / 2;
   canvas.drawBitmap(mStartPlay, offsetW, offsetH, null);
  }
  }
 }
 }
 
 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, 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自定义控件之圆形、圆角ImageViewAndroid实现ImageView阴影和图层效果Android实现ImageView图片缩放和拖动Android实现圆角矩形和圆形ImageView的方式Android使用CircleImageView实现圆形头像的方法Android实现ImageView图片双击放大及缩小Android布局自定义Shap圆形ImageView可以单独设置背景与图片Android长按imageview把图片保存到本地的实例代码


--结束END--

本文标题: Android实现可播放GIF动画的ImageView

本文链接: https://lsjlt.com/news/23987.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Android实现可播放GIF动画的ImageView
    Android的原生控件并不支持播放GIF格式的图片。我们都知道,在Android中如果想要显示一张图片,可以借助ImageView来完成,但是如果将一张GIF图片设置到Ima...
    99+
    2022-06-06
    gif动画 Android
  • Android中播放Gif动画取巧的办法
    由于做的项目,要有个动画的等待效果,第一时间想到的就是Gif(懒,省事),但是试了好多据说能播放Gif的控件,也写过,但是放到魅族手机上就是不能播放,所有就想了个招,既然Gif...
    99+
    2022-06-06
    gif动画 Android
  • Android自定义View播放Gif动画的示例
    前言GIF是一种很常见的动态图片格式,在Android中它的使用场景非常多,大到启动页动画、小到一个Loading展示,都可以用GIF动画来完成,使用也很方便,直接从美工那边拿过来用就成。如果项目赶时间或者自定义原生动画太麻烦,GIF都是一...
    99+
    2023-05-30
    android 播放 gif
  • Android 实现GIF播放的几种方式
    1. Glide播放 Glide是Android上比较常见的图片加载框架,其介绍可以看Android Glide简单使用。 布局文件,GIF文件可以在ImageView里面显示 调用load()方法,导入图片并用ImageView...
    99+
    2023-08-18
    android Gif
  • Android使用glide加载gif动画设置播放次数
    在使用glide加载gif动画,有时需要设置播放的次数,然后播放玩一次或者几次之后,需要在播放完做一些其他的操作,直接看代码: Glide.with(this) ...
    99+
    2022-06-06
    glide gif动画 Android
  • Android加载Gif动画实现代码
    Android加载Gif动画如何实现?相信大家都很好奇,本文就为大家揭晓,内容如下 <?xml version="1.0" encoding="utf-8"...
    99+
    2022-06-06
    gif动画 Android
  • Android中怎么实现动画自动播放功能
    本篇文章给大家分享的是有关Android中怎么实现动画自动播放功能,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。具体如下:private ImageView ...
    99+
    2023-05-31
    android
  • Android中显示GIF动画的实现代码
    本文实例讲述了Android中显示GIF动画的实现代码。分享给大家供大家参考,具体如下: gif图动画在android中还是比较常用的,比如像新浪微博中,有很多gif图片,而且...
    99+
    2022-06-06
    gif动画 Android
  • Android实现ImageView图片缩放和拖动
    今天我们来编写一个缩放效果的ImageView ,网上有很多人都讲了这些。但有许多人都直接使用了库文件, 那么我们今天做的是直接上代码编写一个拖动和缩放的ImageView,具...
    99+
    2022-06-06
    Android
  • Android实现缩放动画
    本文实例为大家分享了Android实现缩放动画的具体代码,供大家参考,具体内容如下 核心方法 public void startAnimation(Animation animati...
    99+
    2024-04-02
  • 怎么在Android中利用ImageView实现一个放大缩小动画
    这期内容当中小编将会给大家带来有关怎么在Android中利用ImageView实现一个放大缩小动画,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。1.配置文件直接添加当直接在布局文件中添加图片的话,可以在自...
    99+
    2023-05-31
    android imageview age
  • android 简单图片动画播放的实例代码
    xml中: 代码如下:        <ImageView   &nb...
    99+
    2022-06-06
    图片 动画 Android
  • html5怎么实现动画播放状态
    今天小编给大家分享一下html5怎么实现动画播放状态的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解...
    99+
    2024-04-02
  • Android手势滑动实现ImageView缩放图片大小
    本文推出了两种Android手势实现ImageView缩放图片大小的方法,分享给大家供大家参考,具体内容如下 方法一: 将以下代码写到MulitPointTouchListen...
    99+
    2022-06-06
    图片 Android
  • iOS的GIF动画效果怎么实现
    本篇文章给大家分享的是有关iOS的GIF动画效果怎么实现,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。GIF在iOS中的使用场景  GIF在iOS中的使用场景有以下三个方面。&...
    99+
    2023-06-04
  • 用Python将动态GIF图片倒放播放的方法
    这次让我们一个用 Python 做一个小工具:将动态 GIF 图片倒序播放! GIF(Graphics Interchange Format) 是一种可以用来呈现动画效果的图片格式,原理就是保存很多帧(F...
    99+
    2022-06-04
    倒放 方法 动态
  • CSS怎么实现CSS动画的暂停与播放
    这篇文章主要讲解了“CSS怎么实现CSS动画的暂停与播放”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“CSS怎么实现CSS动画的暂停与播放”吧!使用纯 CS...
    99+
    2024-04-02
  • Python怎么实现gif动图倒放
    今天小编给大家分享一下Python怎么实现gif动图倒放的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。开发环境 :pycha...
    99+
    2023-06-30
  • android media player实现一个可滑动控制的视频播放器
    五一第一天在家休息, 看了一下视频播放的相关东西 写了一个简单的视频播放器 基础功能: 在屏幕中间滑动: 拖动进度(拖动时隐藏控制面板) 在屏幕...
    99+
    2022-06-06
    media player Android
  • 微信小程序实现自动播放视频模仿gif动图效果实例
    需求背景: 在小程序页面插入gif动态图,但gif图一般体积比较大,转而用自动播放视频的模式来模拟gif图的效果,丰富页面展示。自动播放的视频,无控制条,无声音,自动循环播放。 技术...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作