您的位置:首页 > 其它

可以播放gif动画的ImageView

2014-10-14 15:15 169 查看
一般ImageView并不能播放gif动画。

此处播放gif动画的核心是:

1.将gif中的每一帧拿出来,然后使用Movie类的setTime()和draw()这两个方法来实时的画界面。

2.在ondraw中来处理这些绘制操作。进行逻辑判断,是否自动播放,如果不是自动播放的话就需要绘制一个开始按钮,同事设置画面定位到gif动画的第一帧

其他在代码中查看,主要类GifImageView.java注释比较全,应该看懂问题不大。

注意的是,需要values文件夹下创建attrs,因为需要自定义属性auto_play

package com.pzf.gifaniamtion;

import java.io.InputStream;
import java.lang.reflect.Field;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Movie;
import android.os.SystemClock;
import android.text.method.MovementMethod;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageView;

/**
* 播放动画的主类
*
* @author pangzf
* @time 2014年10月14日 下午2:14:05
*/
public class GifImageView extends ImageView implements OnClickListener {

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;//记录是否正在播放

public GifImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context, attrs);
}
public GifImageView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}

public GifImageView(Context context) {
super(context);
}

private void init(Context context, AttributeSet attrs) {
TypedArray attributes = context.obtainStyledAttributes(attrs,
R.styleable.GifImageView);
// 拿资源id
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);
}
}
}
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if (mMovie != null) {
// 如果是gif的话,设定大小
setMeasuredDimension(mImageWidth, mImageHeight);
}
}

@Override
protected void onDraw(Canvas canvas) {
if (mMovie == null) {
// 普通的图片
super.onDraw(canvas);
} else {
if (isAutoPlay) {
// 如果是gif动画的话,就播放
playMovie(canvas);
invalidate();
} else {
// 不允许自动播放的话
// 1.判断是否正在播放
// 2.获得第一帧的图像
// 3.然后添加播放按钮
if (isPlaying) {
// 如果正在播放就playmoive继续播放
if (playMovie(canvas)) {
isPlaying = false;
}
invalidate();
} else {
// 第一帧
mMovie.setTime(0);
mMovie.draw(canvas, 0, 0);
// 绘制开始按钮
int offsetW = (mImageWidth - mStartPlay.getWidth()) / 2;
int offsetH = (mImageHeight - mStartPlay.getHeight()) / 2;
canvas.drawBitmap(mStartPlay, offsetW, offsetH, null);
}
}

}

}

/**
* 播放gif动画
*
* @param canvas
*/
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);// 设置时间
mMovie.draw(canvas, 0, 0);// 画
if ((now - mMovieStart) >= duration) {
// 结束
mMovieStart = 0;
return true;
}
return false;
}

/**
* 通过反射拿布局中src的资源id
*
* @param attrs
* @param context
* @param attributes
*/
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();
} finally {
if (attributes != null) {
attributes.recycle();
}
}
return 0;
}

@Override
public void onClick(View v) {
if(v.getId()==getId()){
isPlaying=true;
invalidate();
}
}
}
attrs.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>

<declare-styleable name="GifImageView">
<attr name="auto_play" format="boolean"></attr>
</declare-styleable>
</resources>


布局文件

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:attr="http://schemas.android.com/apk/res/com.pzf.gifaniamtion"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
>

<com.pzf.gifaniamtion.GifImageView
android:id="@+id/image_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/gif_animation"
attr:auto_play="false"
/>

</LinearLayout>


如果希望进入自动播放只需将

attr:auto_play="true"


效果图:用的应用包手动截的手机的图效果不好,有需要的可以自己下载源码,那个流畅。



源码地址:

点击打开链接
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: