Android中实现gif动画
一、需求
Android本身没有提供直接显示gif动画的相关控件,因此需要自定义GifImageView类来实现gif的播放,主要是使用的Movie类来解决的。
二、自定义GifImageView
public class GifImageView extends AppCompatImageView {
private static final String TAG = "ImageView";
private static final int DEFAULT_MOVIE_DURATION = 2000;
private Movie mMovie;
private long mMovieStart;
private int mCurrentAnimationTime; /**
* Scaling factor to fit the animation within view bounds.
*/
private float mScale = 1;
private boolean mVisible = true; public GifImageView(Context context) {
this(context, null);
} public GifImageView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
} public GifImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setViewAttributes();
} @SuppressLint("NewApi")
public void setViewAttributes() {
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
} @Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mMovie != null) {
updateAnimationTime();
drawMovieFrame(canvas);
invalidateView();
}
} /**
* Draw current GIF frame
*/
private void drawMovieFrame(Canvas canvas) {
mMovie.setTime(mCurrentAnimationTime);
canvas.save(Canvas.MATRIX_SAVE_FLAG);
canvas.scale(mScale, mScale);
mMovie.draw(canvas, 0, 0);
canvas.restore();
} /**
* Calculate current animation time
*/
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);
} /**
* Invalidates view only if it is visible.
*/
@SuppressLint("NewApi")
private void invalidateView() {
if (mVisible) {
postInvalidateOnAnimation();
}
} @SuppressLint("NewApi")
@Override
public void onScreenStateChanged(int screenState) {
super.onScreenStateChanged(screenState);
mVisible = screenState == SCREEN_STATE_ON;
invalidateView();
} @SuppressLint("NewApi")
@Override
protected void onVisibilityChanged(@NonNull View changedView, int visibility) {
super.onVisibilityChanged(changedView, visibility);
mVisible = visibility == View.VISIBLE;
invalidateView();
} @Override
protected void onWindowVisibilityChanged(int visibility) {
super.onWindowVisibilityChanged(visibility);
mVisible = visibility == View.VISIBLE;
invalidateView();
} public void setMovieResource(int movieResId) {
mMovie = Movie.decodeStream(getResources().openRawResource(movieResId));
requestLayout();
} @Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
if (changed && mMovie != null) {
float scaleW = (float) getWidth() / mMovie.width();
float scaleH = (float) getHeight() / mMovie.height();
mScale = Math.min(scaleH, scaleW);
}
} @Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if (mMovie != null) {
int mMeasureWidth;
int mMeasureHeight;
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
if (widthMode == MeasureSpec.AT_MOST) {
Log.e(TAG, "---moviewidth before" + mMovie.width());
int movieWidth = mMovie.width();
mMeasureWidth = Math.min(movieWidth, widthSize);
Log.e(TAG, "---moviewidth after" + mMovie.width());
} else {
mMeasureWidth = widthSize;
}
if (heightMode == MeasureSpec.AT_MOST) {
Log.e(TAG, "---height " + mMovie.height());
int movieHieght = mMovie.height();
mMeasureHeight = Math.min(movieHieght, heightSize); } else {
mMeasureHeight = heightSize;
}
Log.e(TAG, "--wi : " + mMeasureWidth + " h : " + mMeasureHeight);
setMeasuredDimension(mMeasureWidth, mMeasureHeight);
}
}
}
三、layout中添加控件
<com.pax.view.GifImageView
android:id="@+id/gif"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/space_horizontal"
android:layout_gravity="center"
android:visibility="invisible"/>
四、activity中实现
直接调用set方法,将gif资源传给gifview即可。
例如:
@Bind(R.id.gif)
GifImageView gif;
gif.setMovieResource(R.drawable.gif_searching);
Android中实现gif动画的更多相关文章
- android中设置Animation 动画效果
在 Android 中, Animation 动画效果的实现可以通过两种方式进行实现,一种是 tweened animation 渐变动画,另一种是 frame by frame animation ...
- Android(java)学习笔记199:Android中补间动画(Tween Animation)
本文主要简单介绍补间动画使用代码实现, 关于使用xml实现补间动画,可以参看:自定义控件三部曲之动画篇(一)——alpha.scale.translate.rotate.set的xml属性及用法 1. ...
- 在Android中显示GIF动画
gif图动画在android中还是比较常用的,比如像新浪微博中,有很多gif图片,而且展示非常好,所以我也想弄一个.经过我多方的搜索资料和整理,终于弄出来了,其实github上有很多开源的gif的展示 ...
- 【转】[置顶] 在Android中显示GIF动画
gif图动画在Android中还是比较常用的,比如像新浪微博中,有很多gif图片,而且展示非常好,所以我也想弄一个.经过我多方的搜索资料和整理,终于弄出来了,其实github上有很多开源的gif的展示 ...
- Android(java)学习笔记142:Android中补间动画(Tween Animation)
本文主要简单介绍补间动画使用代码实现, 关于使用xml实现补间动画, 可以参看:自定义控件三部曲之动画篇(一)——alpha.scale.translate.rotate.set的xml属性及用法 1 ...
- Android中的帧动画与补间动画的使用
前言 在日常开发中,我们有时候须要一些好看的动画效果,这时能够充分利用Android提供的这几种动画来实现. Android提供了3种类型的动画: 补间动画:补间动画能够应用于View,让你能够定义一 ...
- Android中的布局动画
简介 布局动画是给布局的动画,会影响到布局中子对象 使用方法 给布局添加动画效果: 先找到要设置的layout的id,然后创建布局动画,创建一个LayoutAnimationController,并把 ...
- Android中使用抖动动画吸引来用户注意
原文:http://www.androidcn.org/topic/552e65bc61d460226ab27a5c 在应用中,有时候我们要吸引用户去点击某些按钮,比如应用市场的推荐按钮,为了能够吸引 ...
- Android 中如何使用动画
1:首先在res/anim/文件夹下建立动画xml文件. 2:在java代码中对UI控件使用动画. //加载动画 Animation myAnim=AnimationUtils.loadAnimati ...
随机推荐
- 从零开始学spring cloud(二) -------- 开始使用Spring Cloud实战微服务
1.准备工作 2.服务提供者与服务消费者 3.服务发现与服务注册 服务发现: 服务注册表: 服务注册表是一个记录当前可用服务实例的网络信息的数据库,是服务发现机制的核心.服务注册表提供查询API和管理 ...
- 轮播插件swiper
使用步骤 1.引用js <script src="swiper/swiper.min.js" type="text/javascript" charset ...
- 记录-springcloud -mybatis(代码)
代码部分: 1:pom文件 <?xml version="1.0" encoding="UTF-8"?> <project xmlns=&qu ...
- SQLServer导入导出命令报错
错误描述: SQL Server阻止了对组件‘xp_cmdshell’的过程‘sys.xp_cmdshell’的访问.因为此组件已作为此服务嚣安全配置的一部分而被关闭. 系统管理员可以通过使用sp_c ...
- RabbitMQ的学习
生成者就是发送信息,消费者就是接收信息,队列就是存储数据的排队.消息通过你的应用程序和RabbitMQ进行传输,它们只能存储在队列中,队列容量没有限制,你要存储多少消息都可以——基本上是一个无限的缓冲 ...
- 关于项目里server清楚缓存的代码
Venk proc存在很多问题,不能应对高并发的情况,所以提供了这个 方法来清理cache, 但是前提是需要有prod的权限: 要想验证是否通过URL清楚了缓存,就要 removeCache url执 ...
- 如何监听Element组件<el-input>标签的回车事件
一.现象 表单提交时需要处理输入框的回车事件,一般的原生input标签可以用@keyup.enter="onSubmit"(tips:onSubmit为定义的方法) 二.解决 1. ...
- 关于python27和windows系统的中文编码问题
最近想写一个python脚本实现对文件夹中的文件进行批量命名.每个文件对应从txt文档中提取出来的一行,因为文件名是中文,所以涉及到了一些中文编码的问题. 脚本运行环境是win10+python27 ...
- dskinlite(uieasy mfc界面库)使用记录4:绘制动态元素(listbox)
效果图: XML代码: 299行的headerctrl只针对listview有效,这里是listbox,忽略 wirelessName,wirelessStatus,wirelessSignal会通过 ...
- 用JDOM和DOM4J解析节点名节点值
1.用JDOM解析节点名和节点值 1.创建一个SAXBuilder对象 2.创建一个输入流, 将xml文件加载到文件中 3. 通过saxBuilder的方法,将输入流加载到saxBuilder 4 ...