2014-10-31Android学习------setContentView(View view)--------GIF动画实现

2022-03-07 13:44:06 浏览数 (1)

我学习Android都是结合源代码去学习,这样比较直观,非常清楚的看清效果,觉得很好,今天的学习源码是网上找的个GIF动画完美实现 源码 百度搜就知道很多下载的地方

这节学习的就是如何让一个GIF格式的文件在手机视图上显示出来,

要想做到这步

1.你需要准备好gif图片,放到drawable下面

2.你需要定义一个ImageView控件 来放置这个图片

3.在activity里面设置这个布局文件

那么问题就来了,我们前面学习的都是这样加载布局

setContentView(R.layout.main);等等这种方法,参数是一个布局文件资源索引

现在我们这里学习另外一种方式,setContentView(View view);

也就是说让我们这个界面以一种视图来加载,很显然我们就需要去定义一个View类。

我们自定义View类,我们在前面26个字母列表的实现中就说到了,想要去自己定义一个View类,必须去继承 android.view.View这个类,然后去重载

onDraw(Canvas canvas)函数就可以实现我们自定义的视图类

接下来看看代码是怎么实现的:

class CustomGifView extends View {

//构造函数 public CustomGifView(Context context) { super(context);//首先需要去构造基类

//这里去初始化你需要的成员变量等等 } //重载它的onDraw(Canvas canvas)函数 public void onDraw(Canvas canvas) { //TODO 处理你想要干的事,就是你想在画布上显示什么东西,这里都可以你自己去写,去设置 } } }

一.这个模式很简单,下面我们要处理的就是如何去实现动态GIF图像的播放了:

要想实现动态图片,我们必须要用到一个类,Movie,这个类就是在Android中解决GIF动画非常方便的一个选择

那么如果我们知道需要这个类,怎么去创建这个 Movie类呢,那么我们需要先去看看API关于这个类的描述了

public class

Movie extends Object

java.lang.Object

android.graphics.Movie

这么多public Methods方法,我们只需要看看 返回值是 Movie类型的函数就可以了

分别是下面的这几个:

1.static Movie decodeByteArray(byte[] data, int offset, int length)

很明白 它将一个byte[]类型的数组转换为一个Movie对象,从哪个位置开始,解析多长

2.static Movie decodeFile(String pathName)

它从将一个文件转换成Movie类

3.static Movie decodeStream(InputStream is)

它是将一个输入流转换成Movie类,

我们可以清楚的看到我们需要去怎么样创建一个Movie类了,方法1和方法3实质差别不大,因为我们可以将 输入流转变为byte[]类型的数组

这里我们使用第三个方法来创造这个类,

1.首先我们需要定义一个成员变量:

public Movie mMovie;

2.我们来初始化这个变量:

mMovie = Movie.decodeStream(getResources().openRawResource(R.drawable.animation));

有人在这里说,你直接给出这句代码我又看不懂了,那么好吧,我们来分析下怎么把一个文件转换成输入流

其实这个很简单,都是系统自定义的函数,我们按 快捷键 / Alt Eclipse立马会给你显示很多函数,那么我们只需要去找它的返回值就可以了,这样的语句就相当于自动生成了

那么我解释这里面用到的函数:

1.首先要找到这个文件

getResources() // 获得当前类所在的文件夹的名字 这个非常的常用,我们要获取一个文件夹下面的文件都用这个函数

Resources android. view. View.getResources()

public Resources getResources ()

Since: API Level 1

Returns the resources associated with this view.

Returns
  • Resources object. 返回值是重点要关注的

2.找到文件之后,我们需要去打开这个文件,也就是操作这个文件,

操作文件肯定要用到open什么之类的,按快捷键 / Alt 肯定很多

openRawResource// 你如果看到一个Raw 要想到这个文件从资源文件索引找到的 ,重要的是关注它的返回值和参数

InputStream android. content. res. Resources.openRawResource( int id) throws NotFoundException

public InputStream openRawResource (int id)

Since: API Level 1

Open a data stream for reading a raw resource. This can only be used with resources whose value is the name of an asset files -- that is, it can be used to open drawable, sound, and raw resources; it will fail on string and color resources.

Parameters

id

The resource identifier to open, as generated by the appt tool.

Returns
  • InputStream Access to the resource data.
Throws

Resources.NotFoundException

Throws NotFoundException if the given ID does not exist.

就这样我们完成了一个Movie类的构造过程了,也就是初始化了

二.当我们构造完成了Movie类,也就是将我们的GIF图片的信息给转存到Movie中去了,接下来我们要干什么呢?

肯定就是将这个信息展示给人看对不,也就是将这个信息画到视图上对不?对的

接下来我们就需要去处理 onDraw(Canvas canvas)这个函数了

在实现一个动画的时候,我们还需要掌握一些 知识

动画一般采用帧形式播放,这就决定我们需要去考虑播放的时间,每帧播放的长度,该帧播放完了之后,需要去更新视图对不对 也就是说这些都是需要在你的函数中去设置了

获得系统时间函数:

long now = android.os.SystemClock.uptimeMillis();

帧播放的开始时间:就是从系统当前的时间开始播放

if (mMovieStart == 0) { // first time //这个变量也需要在成员变量中定义处理 mMovieStart = now; }

开始播放之后,我们就需要设置每帧播放多长时间:

int dur = mMovie.duration(); if (dur == 0) { dur = 1000; }

每帧播放多长时间设置好了,我们就需要去算出该图片需要多少帧能够播放完:

int relTime = (int) ((now - mMovieStart) % dur);

然后把该帧显示出来就行了:

mMovie.setTime(relTime);

当这些设置都做完了,我们需要做的就是将这个Movie 显示到画布上去就行了,这步千万别忘记了,

mMovie.draw(canvas, 0, 0);//0.0表示图片在视图上显示的位置

显示完了,我们还要处理什么?什么呢?哈哈,视图需要更新啊,由于是动画,这帧放完了,赶紧放下帧,那么就涉及到视图的更新了,加一句代码就可以

invalidate();

至此 整个流程就清晰了,下面贴上系统的代码和展示图片:

代码语言:javascript复制
import com.wust.gif.R;

import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Movie;
import android.os.Bundle;
import android.view.View;

public class MainActivity extends Activity {

	public Movie mMovie;
	public long mMovieStart;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(new CustomGifView(this));
	}
	
	class CustomGifView extends View {

		public CustomGifView(Context context) {
			super(context);
			mMovie = Movie.decodeStream(getResources().openRawResource(
					R.drawable.animation));

		}
		
		public void onDraw(Canvas canvas) {

			long now = android.os.SystemClock.uptimeMillis();
			
			if (mMovieStart == 0) { // first time
				mMovieStart = now;
			}
			if (mMovie != null) {
				
				int dur = mMovie.duration();
				if (dur == 0) {
					dur = 1000;
				}
				int relTime = (int) ((now - mMovieStart) % dur);				
				mMovie.setTime(relTime);
				mMovie.draw(canvas, 0, 0);
				invalidate();
			}
		}

	}

}

很简单 什么布局文件都不要,只要这个类,配置到清单文件中去,然后运行就可以,当前你的drawable下面必须有这个GIF图片

0 人点赞