用Movie显示gif(2)GifView
1,类
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.e.weixin.R; public class GifView extends View { /**
* 默认为1秒
*/
private static final int DEFAULT_MOVIE_DURATION = ; private int mMovieResourceId; //要显示的gif的id private Movie mMovie; //用于播放gif等 private long mMovieStart; // private int mCurrentAnimationTime = ; 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);
// super(context, attrs);
} 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.Theme_GifView);
mMovieResourceId = array.getResourceId(R.styleable.GifView_gif, -);
mPaused = array.getBoolean(R.styleable.GifView_paused, false);
array.recycle();
if (mMovieResourceId != -) {
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;
} @Override
protected 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());
}
} @Override
protected 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;
} @Override
protected 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 == ) {
mMovieStart = now;
}
// 取出动画的时长
int dur = mMovie.duration();
if (dur == ) {
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")
@Override
public void onScreenStateChanged(int screenState) {
super.onScreenStateChanged(screenState);
mVisible = screenState == SCREEN_STATE_ON;
invalidateView();
} @SuppressLint("NewApi")
@Override
protected void onVisibilityChanged(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();
}
}
2,自定义view的属性
<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>
</resources>
3,使用到的主题
<style name="Theme.GifView" parent="@android:style/Theme.Dialog">
<!--...-->
</style>
不用非继承 @android:style/Theme.Dialog 不可,其它主题也可以。
用Movie显示gif(2)GifView的更多相关文章
- Android显示GIF动画 GifView
android中显示gif动画原生态一般支持的不是很好,故找了一个开源的项目,现简单介绍如下: GifView 是一个为了解决android中现在没有直接显示gif的view,只能通过mediapla ...
- IOS 播放动态Gif图片
图片分为静态和动态两种,图片的格式有很多种,在开发中比较常见的是.png和.jpg的静态图片,但有的时候在App中需要播放动态图片,比如.gif格式的小表情头像,在IOS中并没有提供直接显示动态图片的 ...
- iOS播放gif图方式
转发:http://www.cnblogs.com/jerehedu/ 图片分为静态和动态两种,图片的格式有很多种,在开发中比较常见的是.png和.jpg的静态图片,但有的时候在App中需要播放动态图 ...
- Android—基于GifView显示gif动态图片
android中显示gif动态图片用到了开源框架GifView 1.拷GifView.jar到自己的项目中. 2.将自己的gif图片拷贝到drawable文件夹 3.在xml文件中设置基本属性: &l ...
- Android开源项目:GifView——Android显示GIF动画
下载:http://code.google.com/p/gifview/downloads/list 简介:android中现在没有直接显示gif的view,只能通过mediaplay来显示,且还常常 ...
- android -------- GifView 显示gif图片
最近的项目需要在界面显示Gif动图,查找网络资料,总结了一下,分享一下, 一个GifView的gif图加载库以有效地显示GIF, 您可以启动,暂停和停止gifView 在app 的 build.gra ...
- Android中轻松显示Gif图片
android中现在没有直接显示gif的view,只能通过mediaplay来显示,且还常常不能正常显示出来,为此写了这个gifview,其用法和imageview一样使用方法:1-把GifView. ...
- 新浪微博客户端(31)-显示相册图片上的GIF标记
DJStatusPhotoView.h #import <UIKit/UIKit.h> @class DJPhoto; @interface DJStatusPhotoView : UII ...
- Android UI 组件 » GifView
GifView 是一个为了解决android中现在没有直接显示gif的view,只能通过mediaplay来显示这个问题的项目,其用法和 ImageView一样,支持gif图片 使用方法: 1-把Gi ...
随机推荐
- android开发里跳过的坑——调用已安装视频播放器在有些机器上无效
调用已安装视频播放器播放未修改之前的代码 private void startPlay(String fileName){ File file = new File(fileName); Intent ...
- csu - 1536: Bit String Reordering (模拟)
http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1536 不知道为何怎么写都写不对. 这题可以模拟. 虽然题目保证一定可以从原串变成目标串,但是不一定 ...
- 2017-10-01-morning
T1 位运算1(bit) Time Limit:1000ms Memory Limit:128MB 题目描述 LYK拥有一个十进制的数N.它赋予了N一个新的意义:将N每一位都拆开来后再加起来就是N ...
- mysql计算两个日期之间的天数
MYSQL自带函数计算给定的两个日期的间隔天数 有两个途径可获得 1.利用TO_DAYS函数 select to_days(now()) - to_days('20120512') 2 ...
- Java循环中删除一个列表元素
本文主要想讲述一下我对之前看到一篇文章的说法.假设跟你的想法有出入,欢迎留言.一起讨论. #3. 在循环中删除一个列表元素 考虑以下的代码.迭代过程中删除元素: ArrayList<String ...
- hdu 2544 最短路(SPFA算法)
本题链接:点击打开链接 本题大意: 首先输入一个n,m.代表有n个点.m条边.然后输入m条边,每条边输入两个点及边权.1为起点,n为终点.输入两个零表示结束. 解题思路: 本题能够使用SPFA算法来做 ...
- 实战c++中的vector系列--vector的一些异常
今天就写一写vector的一些异常.能够捕捉的异常. out_of_range 相当于数组的越界了.vector会自己主动增大容量,可是假设索引超出了当前的size.就会引发异常. #include& ...
- 运行shell脚本报错 '\357\273\277': command not found 解决的方法
1,删除BOM,在vi以下运行以下的命令就可以 :set nobomb 2,原因: 所谓BOM,全称是Byte Order Mark.它是一个Unicode字符,通常出如今文本的开头,用来标识字节序( ...
- 【Android】自己定义View、画家(画布)Canvas与画笔Paint的应用——绘图、涂鸦板app的实现
利用一个简单的绘图app来说明安卓的图形处理类与自己定义View的应用. 例如以下图,有一个供用户自己随意绘图.涂鸦的app. 这里不做那么花俏了,仅提供黑白两色.但能够改变笔尖的粗细. 实质上这里的 ...
- C中多线程开发
1 引言 线程(thread)技术早在60年代就被提出,但真正应用多线程到操作系统中去,是在80年代中期.solaris是这方面的佼佼者.传统的 Unix也支持线程的概念,可是在一个进程(proce ...