前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android开发笔记(十七)GIF动画的实现GifAnimation

Android开发笔记(十七)GIF动画的实现GifAnimation

作者头像
aqi00
发布2019-01-18 10:30:52
1.2K0
发布2019-01-18 10:30:52
举报
文章被收录于专栏:老欧说安卓

GIF在Windows上是常见的图片格式,主要用来播放短小的动画。但在手机上由于系统资源紧张,所以Android并没有直接支持GIF格式,如果在ImageView中放入一张gif文件,你会发现显示出来的只是该gif文件的第一帧图片。 对于这种情况,Android带来了帧动画技术,通过连续播放每帧图片,从而实现帧动画的效果。不过若要使用帧动画,我们得自己准备好若干帧,然后把这些图片帧编入图片队列,这样才可以显示动画。对于如何从gif文件中提取出每帧图片,博主在之前的文章中有做了说明,详见《Android开发笔记(十)常用的图片加工操作》。 可是手工分解gif文件也太麻烦了,如果gif数量多的话,岂不累坏了。能否通过代码直接从gif文件中提取每帧图片呢?答案是有的,已经有大牛研究出来了,那么我们直接把相关算法拿过来,改改就可以用了。下面是调用的代码例子,为方便比较帧动画和GIF动画的效果,代码同时实现了两种动画

代码语言:javascript
复制
import java.io.InputStream;

import com.example.exmgif.util.GifImage;
import com.example.exmgif.util.GifImage.GifFrame;

import android.app.Activity;
import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;

public class MainActivity extends Activity implements OnClickListener {

	private ImageView iv_gif;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		Button btn_play1 = (Button) findViewById(R.id.btn_play1);
		Button btn_play2 = (Button) findViewById(R.id.btn_play2);
		btn_play1.setOnClickListener(this);
		btn_play2.setOnClickListener(this);
		iv_gif = (ImageView) findViewById(R.id.iv_gif);
	}
	
	private Drawable getDraw(int id) {
		return getResources().getDrawable(id);
	}
	
	private void showFrameAnimation() {
		//帧动画需要把每帧图片加入AnimationDrawable队列
		AnimationDrawable animationList = new AnimationDrawable();
		animationList.addFrame(getDraw(R.drawable.flow_p1), 50);
		animationList.addFrame(getDraw(R.drawable.flow_p2), 50);
		animationList.addFrame(getDraw(R.drawable.flow_p3), 50);
		animationList.addFrame(getDraw(R.drawable.flow_p4), 50);
		animationList.addFrame(getDraw(R.drawable.flow_p5), 50);
		animationList.addFrame(getDraw(R.drawable.flow_p6), 50);
		animationList.addFrame(getDraw(R.drawable.flow_p7), 50);
		animationList.addFrame(getDraw(R.drawable.flow_p8), 50);
		//setOneShot为true表示只播放一次,为false表示循环播放
		animationList.setOneShot(false);
		iv_gif.setImageDrawable(animationList);
		animationList.start();
	}

	private void showGifAnimation(int resid) {
		InputStream is = getResources().openRawResource(resid);
		GifImage gifImage = new GifImage();
		int code = gifImage.read(is);
		if (code == GifImage.STATUS_OK) {  
			GifFrame[] frameList = gifImage.getFrames();
			AnimationDrawable gifList = new AnimationDrawable();
			for (int i=0; i<frameList.length; i++) {
				//BitmapDrawable用于把Bitmap格式转换为Drawable格式
				BitmapDrawable bitmapDrawable = new BitmapDrawable(getResources(), frameList[i].image);
				gifList.addFrame(bitmapDrawable, frameList[i].delay);
			}
			gifList.setOneShot(false);
			iv_gif.setImageDrawable(gifList);
			gifList.start();
        } else if (code == GifImage.STATUS_FORMAT_ERROR) {
			Toast.makeText(this, "该图片不是gif格式", Toast.LENGTH_LONG).show();
        } else {
			Toast.makeText(this, "gif图片读取失败:"+code, Toast.LENGTH_LONG).show();
        }
	}
	
	@Override
	public void onClick(View v) {
		if (v.getId() == R.id.btn_play1) {
			showFrameAnimation();
		} else if (v.getId() == R.id.btn_play2) {
			showGifAnimation(R.drawable.welcome);
		}
	}

}

可以看到帧动画并非补间动画那样有专门的Animation类,而是通过AnimationDrawable来实现(又是Drawable)。另外,代码在从gif文件抽取每帧图片时,用到了BitmapDrawable,该类可把Bitmap格式转换为Drawable格式。不知不觉,我们已经应用了十几个Drawable中的大半,它们分别是: 1、StateListDrawable:详见《Android开发笔记(七)初识Drawable》 2、ShapeDrawable:详见《Android开发笔记(八)神奇的shape》 3、NinePatchDrawable:详见《Android开发笔记(九)特别的.9图片》 4、TransitionDrawable:详见《Android开发笔记(十五)淡入淡出动画》 5、AnimationDrawable:见本文《Android开发笔记(十七)GIF动画的实现》 6、BitmapDrawable:见本文《Android开发笔记(十七)GIF动画的实现》 7、GradientDrawable:详见《Android开发笔记(十八)书籍翻页动画》 下面是GIF动画和帧动画的效果图

点击下载本文用到的GIF动画和帧动画的工程代码 点此查看Android开发笔记的完整目录

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2015年12月11日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档