一般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"
效果图:用的应用包手动截的手机的图效果不好,有需要的可以自己下载源码,那个流畅。
源码地址:
时间: 2024-10-16 22:58:33