Android应用系列:完美运行GIF格式的ImageView(附源码)
前言
我们都知道ImageView是不能完美加载Gif格式的图片,如果我们在ImageView中src指定的资源是gif格式的话,我们将会惊喜的发觉画面永远停留在第一帧,也就是不会有动画效果。当然,经过略加改造,我们是可以让gif在ImageView上完美加载的。
正文
Android给我们提供了一个Movie类,可以让我们实现加载gif格式资源的目标。我们需要导入android.graphics.Movie这个包,当然这个也是Android自带的。所以我们的主要方法是继承一个ImageView的子类,通过改写其中的onDraw方法加载gif资源。话也不多说了,通过代码大家看的更明白,文末附带源码哦。
PS:看懂本文需要了解自定义View的相关知识。
attrs资源文件:
<resources>
<declare-styleable name="GifView">
<attr name="isgifimage" format="boolean"/>
</declare-styleable>
</resources>
我在这里面设置了一个自定义属性 isgifimage,目的是让用户自行设置控件显示是否是gif格式资源,因为非gif格式资源用Movie加载也是可以显示图像,但是效率就肯定没有原生控件加载模式好,当然,默认isgifimage为true,也就是默认为gif格式的资源。
自定义的GifView的构造函数(GifView类继承ImageView)
public GifView(Context context, AttributeSet attrs) {
super(context, attrs);
//获取自定义属性isgifimage
TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.GifView);
isGifImage = array.getBoolean(R.styleable.GifView_isgifimage, true);
array.recycle();//获取自定义属性完毕后需要recycle,不然会对下次获取造成影响
//获取ImageView的默认src属性
image = attrs.getAttributeResourceValue( "http://schemas.android.com/apk/res/android", "src", 0);
movie = Movie.decodeStream(getResources().openRawResource(image));
}
在GifView的构造方法中,我们主要是对GifView的自定义属性进行获取。可以通过context.obtainStyledAttributes(attrs, R.styleable.GifView)返回一个TypedArray对象,然后从该对象分别获取自定义属性,在这里需要强调一点的时R.styleable.GifView_isgifimage,红色的时attrs资源文件的名字,而蓝色则是其对应的属性名字(见attrs资源文件),中间以下划线分隔。
在我们获取完自定义属性后必须recycle(),不然会对下次该控件获取自定义属性造成影响,因为TypedArray对象是公共资源。
然后我们在通过attrs.getAttributeResourceValue( "http://schemas.android.com/apk/res/android", "src", 0)来获取ImageView的原生src属性,并将其传入movie实例中。
自定义GifView的onDraw方法
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);//执行父类onDraw方法,绘制非gif的资源
if(isGifImage){//若为gif文件,执行DrawGifImage(),默认执行
DrawGifImage(canvas);
}
} private void DrawGifImage(Canvas canvas) {
//获取系统当前时间
long nowTime = android.os.SystemClock.currentThreadTimeMillis();
if(movieStart == 0){
//若为第一次加载,开始时间置为nowTime
movieStart = nowTime;
}
if(movie != null){//容错处理
int duration = movie.duration();//获取gif持续时间
//如果gif持续时间小于100,可认为非gif资源,跳出处理
if(duration > 100){
//获取gif当前帧的显示所在时间点
int relTime = (int) ((nowTime - movieStart) % duration);
movie.setTime(relTime);
//渲染gif图像
movie.draw(canvas, 0, 0);
invalidate();
}
}
}
在这个方法中,我们先对isGifImage是否为true进行判断,如果开发者指定其为false则直接调用super.onDraw(canvas)绘制即可,而不必调用DrawGifImage()来降低效率,毕竟不断的invalidate()对性能效率还是蛮大的。
如果要绘制gif资源,我们会根据系统的时间来推断出当前时间点时gif资源所应该显示的时间帧,相信大家看代码更容易看懂,注释也够详细的了,就不多讲解了。
调用资源的xml文件:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:gifview="http://schemas.android.com/apk/res/com.net168.testgifview"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<com.net168.gifview.GifView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/image"
gifview:isgifimage="true"
/>
</LinearLayout>
需要注意的一点就是 xmlns:gifview="http://schemas.android.com/apk/res/com.net168.testgifview",其中红色部分GifView.java这个类所在的包名。
下面附上源码(GifView.rar为lib工程,TestGIfView.rar为调试工程):MyGif.rar
作者:enjoy风铃
出处:http://www.cnblogs.com/net168/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则下次不给你转载了
Android应用系列:完美运行GIF格式的ImageView(附源码)的更多相关文章
- Android 音视频深入 四 录视频MP4(附源码下载)
本篇项目地址,名字是<录音视频(有的播放器不能放,而且没有时长显示)>,求star https://github.com/979451341/Audio-and-video-learnin ...
- openlayers5-webpack 入门开发系列结合 turf.js 实现等值线(附源码下载)
前言 openlayers5-webpack 入门开发系列环境知识点了解: node 安装包下载webpack 打包管理工具需要依赖 node 环境,所以 node 安装包必须安装,上面链接是官网下载 ...
- 【Android初级】如何动态添加菜单项(附源码+避坑)
我们平时在开发过程中,为了灵活多变,除了使用静态的菜单,还有动态添加菜单的需求.今天要分享的功能如下: 在界面的右上角有个更多选项,点开后,有两个子菜单:关于和退出 点击"关于", ...
- openlayers4 入门开发系列之地图模态层篇(附源码下载)
前言 openlayers4 官网的 api 文档介绍地址 openlayers4 api,里面详细的介绍 openlayers4 各个类的介绍,还有就是在线例子:openlayers4 官网在线例子 ...
- Android 音视频深入 二 AudioTrack播放pcm(附源码下载)
本篇项目地址,名字是录音和播放PCM,求starhttps://github.com/979451341/Audio-and-video-learning-materials 1.AudioTrack ...
- EasyPlayer Android安卓流媒体播放器实现播放同步录像功能实现(附源码)
本文转自EasyDarwin团队John的博客:http://blog.csdn.net/jyt0551,John是EasyPusher安卓直播推流.EasyPlayer直播流媒体播放端的开发和维护者 ...
- openlayers4 入门开发系列之地图标绘篇(附源码下载)
前言 openlayers4 官网的 api 文档介绍地址 openlayers4 api,里面详细的介绍 openlayers4 各个类的介绍,还有就是在线例子:openlayers4 官网在线例子 ...
- openlayers4 入门开发系列之地图属性查询篇(附源码下载)
前言 openlayers4 官网的 api 文档介绍地址 openlayers4 api,里面详细的介绍 openlayers4 各个类的介绍,还有就是在线例子:openlayers4 官网在线例子 ...
- openlayers4 入门开发系列之地图空间查询篇(附源码下载)
前言 openlayers4 官网的 api 文档介绍地址 openlayers4 api,里面详细的介绍 openlayers4 各个类的介绍,还有就是在线例子:openlayers4 官网在线例子 ...
随机推荐
- 信号基础知识----线性调频信号LFM //matlab命令:chirp
%关于线性调频信号(LFM) %参考书目:声呐技术,第二章P33 clc;close all;clear all;%参数----------------------------------f0=100 ...
- java_22 Map接口
1Map Collection是孤立存在的,向集合中存储元素是一个一个放进去的 Map中的集合存储是成对的,可以通过键找到值.即将键映射到值的对象.一个映射不能包含重复的键:每个键最多只能映射到一个值 ...
- AI绘制毛线的小技巧
1.新建一个500*500的画布. 2.绘制一个大小一样的正方形[颜色#060B1d] 3.绘制圆形1pt描边. 4. ctrl+c ctrl+F 原位复制圆形等比 ...
- Java SSM 框架相关基础面试题
一.Spring 面试题 1. Spring 在 SSM 中起什么作用? Spring 是轻量级框架,作用是作为 Bean 工厂,用来管理 Bean 的声明周期和框架集成. Spring 的两大核心: ...
- sql server中replace()函数用法解析
知识点一:replace()的语法 REPLACE ( string_replace1 , string_replace2 , string_replace3 ) 参数解析: string_repla ...
- Linux学习--- 宏定义下#、##的使用
# 字符串化 ## 连接符号 eg: #include <stdio.h> #define ABC(x) #x #define DAY(c) myday##c int main (){ ...
- Java程序员职业生涯规划
一.规划 工作3年了,感觉自己的技术现在到了一个瓶颈,在做一些重复性的业务性的工作,没有长进,提高太慢:因此停下脚步对自己的职业生涯做了一个规划,并为之努力奋斗: 20-27岁:技术积累阶段在这 5 ...
- SignalR 服务器系统配置要求
SignalR 所支持的服务器版本..NET Framework 版本.IIS和其他组件. SignalR操作系统要求 SignalR组件能够运行在下面的服务器和客户端操作系统.需要注意的是使用Web ...
- AdminLTE用django部署
前言 最近从网上看到AdminLTE这个web前端的主题挺好的,我平时用python就是写一些后台,准备以后就用这个框架了,这里就是把这个用django初始化一下这个项目. 基础环境介绍 Python ...
- Python logging模块简介
logging模块提供logger,handler,filter,formatter. logger:提供日志接口,供应用代码使用.logger最长用的操作有两类:配置和发送日志消息.可以通过logg ...