摘自博客:

在Android中显示GIF动画

在这里主要用的是:android中的android.graphics.Movie 这个类,这是android提供给我们的一个非常方便的工具。

Movie其实管理着GIF动画中的多个帧,只需要通过 setTime() 一下就可以让它在draw()的时候绘出相应的那帧图像。通过当前时间与duration之间的换算关系,是很容易实现GIF动起来的效果。

1、自定义view:

package com.example.lenovo.myapplication.activity;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;import com.example.lenovo.myapplication.R;/*** Created by lenovo on 2017/7/4.*/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();}
}

2、res/value/attrs:

<?xml version="1.0" encoding="utf-8"?>
<resources><declare-styleable name="gifView"><attr name="gif" format="reference" /><attr name="paused" format="boolean" /></declare-styleable><declare-styleable name="CustomTheme"><attr name="gifViewStyle" format="reference" /></declare-styleable><style name="Widget_GifView"></style>
</resources>

3、布局:

    <com.example.lenovo.myapplication.activity.GifViewandroid:id="@+id/gif1"android:layout_width="match_parent"android:layout_height="222dp"android:layout_gravity="center_horizontal"android:enabled="false" /><com.example.lenovo.myapplication.activity.GifViewandroid:id="@+id/gif2"android:layout_width="200dp"android:layout_height="200dp"android:layout_gravity="center_horizontal"android:enabled="false" />

4、使用:

/*** Created by lenovo on 2017/7/4.*/public class MainActivityII extends AppCompatActivity {private GifView gif1, gif2;@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);gif1 = (GifView) findViewById(R.id.gif1);// 设置背景gif图片资源gif1.setMovieResource(R.raw.boliang);gif2 = (GifView) findViewById(R.id.gif2);gif2.setMovieResource(R.raw.boliang);// 设置暂停gif2.setPaused(true);}}

遇到问题:

1、未设置抗锯齿:

    private void drawMovieFrame(Canvas canvas) {// 设置要显示的帧,绘制即可mMovie.setTime(mCurrentAnimationTime);canvas.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG| Paint.FILTER_BITMAP_FLAG));//在此方法中为canvas添加抗锯齿canvas.save(Canvas.MATRIX_SAVE_FLAG);canvas.scale(mScale, mScale);mMovie.draw(canvas, mLeft / mScale, mTop / mScale);canvas.restore();}

参考:Android画图之抗锯齿paint和Canvas两种方式实例

设置抗锯齿方法:

方法一:给Paint加上抗锯齿标志。然后将Paint对象作为参数传给canvas的绘制方法。

 paint.setAntiAlias(true);

方法二:给Canvas加上抗锯齿标志。
有些地方不能用paint的,就直接给canvas加抗锯齿,更方便。

canvas.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG|Paint.FILTER_BITMAP_FLAG));

Android-GIF图片显示相关推荐

  1. Android ImageView图片显示点击背景切换

    为什么80%的码农都做不了架构师?>>>    一.介绍 ImageView用来显示任意图像图片,可以自己定义显示尺寸,显示颜色等等. 二.XML属性 android:adjustV ...

  2. 开发微信小程序,导入使用本地图片,Android手机上测试图片显示空白

    微信小程序中,导入使用本地图片,开发时在电脑上显示正常,iOS上也能正常显示,但是在Android上图片显示空白, 如图: 原因:网上查找,说有可能是这些原因 1.image src中的图片地址对英文 ...

  3. android动态图片适配,android Drawble、Shape实现图像适配和优化

    一.屏幕适配说明 在android开发过程中,屏幕适配是一件非常重要的工作,主要原则有以下几点 对于控件而言,尽量不要使用固定的宽度和高度,但推荐使用固定的外边距局和内边距. 对于drawable-x ...

  4. android 加载显示富文本——TextView显示富文本和WebView显示富文本,WebView显示图片适配屏幕宽度

    TextView加载显示 添加依赖 implementation 'com.zzhoujay.richtext:richtext:3.0.8' implementation 'com.zzhoujay ...

  5. android动态设置文本居中显示图片,Android DrawableTextView图片文字居中显示实例

    在我们开发中,TextView设置Android:drawableLeft一定使用的非常多,但Drawable和Text同时居中显示可能不好控制,有没有好的办法解决呢? 小编的方案是通过自定义Text ...

  6. Android自定义控件ImageViwe(一)——依据控件的大小来设置缩放图片显示

    功能: 自定义 ImageView 设置显示图片,如果图片的宽与高小于控件的宽与高,就将图片设置显示到控件的中央, 如果图片的宽与高有一项大于控件的宽与高,那么就将图片进行缩放显示,两者者是显示在控件 ...

  7. tomcat给android发图片,一步一步学会http获取tomcat服务端的图片,在android客户端显示...

    最简单的利用服务端来下载图片到客户端上面,刚开始接触,记录一下,同时希望帮助到新人. 在看本篇文章之前,你可以先看下这两篇文章 加载web项目时报的错误:Tomcat version 6.0 only ...

  8. android webview 太大,Android应用开发之Android WebView加载图片显示过大的处理教程(代码教程)...

    本文将带你了解Android应用开发Android  WebView加载图片显示过大的处理教程(代码教程),希望本文对大家学Android有所帮助. Webview加载图片时,经常会遇到图片显示不符合 ...

  9. android图片显示代码,Android图片处理:识别图像方向并显示(示例代码)

    在Android中使用ImageView显示图片的时候发现图片显示不正.方向偏了或者倒过来了. 解决问题非常自然想到的分两步走:1.自己主动识别图像方向,计算旋转角度. 2.对图像进行旋转并显示. 一 ...

  10. Android用ImageView显示本地和网上的图片

    ImageView是Android程序中经常用到的组件,它将一个图片显示到屏幕上. 在UI xml定义一个ImageView如下: public void onCreate(Bundle savedI ...

最新文章

  1. 爆改古董卡西欧计算器!能联网、能聊天,「作弊神器」只要150块
  2. 为什么引入验证集来评估机器学习模型?只用训练集和测试集可以吗?
  3. 7 成中国职场人厌班,我们为什么会陷入职业倦怠?
  4. matlab四节点矩形单元的应变,四节点矩形单元有限元解读.ppt
  5. 解决nginx+php二级页面显示空白的问题
  6. equals方法重写详解
  7. Google开源的AR/VR开发库Lullaby
  8. python时间差怎么转换为数字_pandas进行时间数据的转换和计算时间差并提取年月日...
  9. lex和yacc环境配置
  10. VSFTPD Centos 7.6 _配置篇
  11. oracle 两表两列数据对比_Oracle、PostgreSQL与Mysql数据写入性能对比
  12. linux端口接收中文乱码,linux中显示中文乱码如何解决
  13. thinkphp5 验证码出不来的常见问题
  14. 华三ap设置无线服务器,H3C无线控制器实现Remote AP功能典型配置举例(V7)
  15. STM32应用笔记分类汇总,值得收藏
  16. 2021年中国云游戏产业发展环境(PEST)分析:中国云游戏服务拥有光明前景[图]
  17. eclipse windows 窗口背景颜色 保护视力
  18. 643. Maximum Average Subarray I*
  19. Camera4 MTK camera驱动结构介绍
  20. 自学Java的心路历程

热门文章

  1. python中fetch_python 异步 fetch demo
  2. solidwork 侵权 证据_刑事案件辩护律师证据质证的“分层”模式
  3. ubuntu释放显卡内存
  4. html5 css3时间特效,炫酷纯CSS3响应式垂直时间轴特效
  5. 并行接口芯片8255与定时器/计数器接口芯片8253
  6. Ionic4—UI组件之ion-backdrop组件
  7. win7笔记本做wifi热点
  8. [摘]广义企业级PDM系统下的PPM(工艺规划管理)
  9. 一个节拍都不错过——dfuse 2019年第三季度回顾
  10. 【转】艺术设计、数字媒体、环艺、影视动画、摄影、广编专业…等…视频、教程、资讯、图库、作品汇总大全