可以播放gif动画的ImageView

一般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

可以播放gif动画的ImageView的相关文章

能够播放gif动画的ImageView

一般ImageView并不能播放gif动画. 此处播放gif动画的核心是: 1.将gif中的每一帧拿出来,然后使用Movie类的setTime()和draw()这两个方法来实时的画界面. 2.在ondraw中来处理这些绘制操作.进行逻辑推断,是否自己主动播放,假设不是自己主动播放的话就须要绘制一个開始button,同事设置画面定位到gif动画的第一帧 其它在代码中查看.主要类GifImageView.java凝视比較全.应该看懂问题不大. 注意的是,须要values目录下创建attrs,由于须要

android 拓展ImageView播放GIF动画

原生Android控件ImageView并不能支持播放GiF格式的图片.如果将一张GIF的图片放入ImageView中,它只会显示图片的第一帧,不会产生任何动画效果. Android中播放GIF动画实现方法还是用多种的,最常用的就是使用   Frame动画, 但局限性较多,所以下面用一种拓展的ImageView实现效果. 1.要用到自定义控件,就要使用自定义控件的属性,因此需要在values下新建一个attrs.xml,可以为这个文件中添加任何需要自定义的属性. 这里只需要一个auto_play

[Swift通天遁地]八、媒体与动画-(10)在项目中播放GIF动画

本文将演示使用第三方类库播放GIF动画. 首先确保已经安装了所需的第三方类库.双击查看安装配置文件[Podfile] 1 platform :ios, '12.0' 2 use_frameworks! 3 4 target 'DemoApp' do 5 source 'https://github.com/CocoaPods/Specs.git' 6 pod 'SwiftGifOrigin', '~> 1.6.1' 7 end 根据配置文件中的相关设置,安装第三方类库. 安装完成之后,双击打开项

cocos2d 播放GIF动画类

cocos2d 播放GIF动画类 以前项目中曾经用到过,后来因为GIF图像的质量较差,被弃用了,把公司名字去掉分享下,根据网上资料改编的cocos2d-iphone版的. // // CCSpriteGif.h // // Created by Yuming on 13-1-23. // Copyright 2013年 __MyCompanyName__. All rights reserved. // // 本类需要导入ImageIO.framework #import <Foundation

【v2.x OGE-example 第三节 播放精灵动画】

1. 位置:Drawing_example --> SpriteAnimated 2. 类名:SpriteAnimated 3.利用AnimatedSprite动画精灵类能够实现多种多种动作. 比如: (1).播放精灵动画,指定播放速度: (2).播放特定帧,指定特定每一帧的帧速,能够实现慢放,快进,跳帧.倒放等. (3).能够循环播放,也能够仅仅播放一次,也能够指定播放次数: (4).增加监听器.全然掌握动画的播放状态,開始?结束?播到第几帧?是否播放完?循环了几次: 4.一下是Animate

Unity3D中播放序列帧动画

[狗刨学习网] class FrameAnimation { private float fps = 10.0f; private Rect drawPos; private float time = 0; private int currentIndex = 0; public void DrawFrameAnimation(Texture[] frameTex) { int length = frameTex.Length; GUI.DrawTexture(drawPos, frameTex

关于Cocos Creator用js脚本代码播放骨骼动画的步骤和注意事项

1.用cc.find()方法找到相应的骨骼动画节点,并把这个对象赋值给一个var出来的新对象. 具体代码:var spineboy_anim = cc.find("UI_Root/anchor_lb/spineboy"); 2.用getComponent()方法找到相应骨骼动画节点的骨骼动画组件,并把这个对象赋值给一个var出来的新对象. 具体代码:var ske_anim_comp = spineboy_anim.getComponent(sp.Skeleton); 3.把第二点的新

iOS 播放Gif动画

// //  loadGifView.h //  PlayGif // //  Created by 寒竹子 on 15/4/27. //  Copyright (c) 2015年 寒竹子. All rights reserved. // #import <UIKit/UIKit.h> @interface loadGifView : UIView /** *  @brief 初始化 * *  @return */ - (instancetype)initWithFrame:(CGRect)f

【原创】测试不同浏览器播放canvas动画的平滑程度

Canvas无疑是HTML5开放式网络平台最激动人心的技术之一.目前,除了IE8以外,各类浏览器的新版本都支持HTML5 Canvas. 程序员需要通过Javascript调用Canvas API.基本的Canvas API包括一个2D环境,该环境允许程序员绘制各种图形和渲染文本,并将图像显示在浏览器窗口的定义区域.实现Canvas动画时,程序员需要在下一帧渲染前设置屏幕内容,重绘图像以实现动画效果.Canvas动画的实现有点儿像“翻页动画”,在绘本上的每页绘制不同图像,快速翻过时每一帧都连续起