Android 简单动画中SurfaceView 的应用

 一、对SurfaceView  的认识:     

    在Android中,SurfaceView是View的子类,它内嵌了一个专门用于绘制的Surface,我们可以控制这个Surface的格式和尺寸,Surfaceview控制这个Surface的绘制位置。surface是纵深排序(Z-ordered)的,说明它总在自己所在窗口的后面。SurfaceView提供了一个可见区域,只有在这个可见区域内的surface内容才可见。surface的排版显示受到视图层级关系的影响,它的兄弟视图结点会在顶端显示。这意味者 surface的内容会被它的兄弟视图遮挡,这一特性可以用来放置遮盖物(overlays)(例如,文本和按钮等控件)。注意,如果surface上面有透明控件,那么每次surface变化都会引起框架重新计算它和顶层控件的透明效果,这会影响性能。SurfaceView默认使用双缓冲技术的,它支持在子线程中绘制图像,这样就不会阻塞主线程了,所以它更适合于游戏的开发。

  SurfaceView使用的方式与任何View所派生的类都是完全相同的。可以像其他View那样应用动画,并把它们放到布局中。SurfaceView封装的Surface支持所有标准的Canvas方法进行绘图,同时也支持完全的OpenGL ES 库。

二、创建SurfaceView控件:

   首先我们需要继承SurfaceView并实现SurfaceHolder.Callback接口,这是因为使用SurfaceView 有一个原则,所有的绘图工作必须得在Surface 被创建之后才能开始(Surface—表面,这个概念在 图形编程中常常被提到。基本上我们可以把它当作显存的一个映射,写入到Surface 的内容可以被直接复制到显存从而显示出来,这使得显示速度会非常快),而在Surface 被销毁之前必须结束。所以Callback 中的surfaceCreated 和surfaceDestroyed 就成了绘图处理代码的边界。接着我们需要实现它的3个方法:

1. surfaceCreated(SurfaceHolder holder):surface创建的时候调用,一般在该方法中启动绘图的线程。
2. surfaceChanged(SurfaceHolder holder, int format, int width,int height):surface尺寸发生改变的时候调用,如横竖屏切换。
3. surfaceDestroyed(SurfaceHolder holder) :surface被销毁的时候调用,如退出游戏画面,一般在该方法中停止绘图线程。
同时,我们还需要获得SurfaceHolder,并添加回调函数holder.addCallback(this);,这样这三个方法才会执行。另外,在绘制时,锁定画布,画布用完后要释放holder.unlockCanvasAndPost(canvas);

 

Android 简单动画的代码:

MainActivity.java

 

package com.example.cartoon;

import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;

public class MainActivity extends ActionBarActivity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		//实例化SurfaceView
		BallSurfaceView sv = new BallSurfaceView(this);
		setContentView(sv);
	}
	
}

 

BallSurfaceView.java

 

package com.example.cartoon;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class BallSurfaceView extends SurfaceView implements SurfaceHolder.Callback, Runnable{
	private SurfaceHolder holder;
	private boolean runFlag;
	private Paint paint = new Paint();
	
	//重写构造方法
	public BallSurfaceView(Context context) {
		this(context, null);	
	}
	
	public BallSurfaceView(Context context, AttributeSet attrs) {
		this(context, attrs, 0);	
	}
	
	public BallSurfaceView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		//获取Surface句柄对象,通过该对象获取画布
		holder = this.getHolder();
		//添加回调接口
		holder.addCallback(this);
//		setFocusable(true);		
	}
	
	//实现SurfaceHolder.Callback接口的方法
	@Override//当切换横竖屏时调用
	public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
		
	}

	//当SurfaceView创建时调用
	@Override
	public void surfaceCreated(SurfaceHolder arg0) {
		//创建时启动线程
		runFlag = true;
		new Thread(this).start();		
	}

	//当SurfaceView结束时调用
	@Override
	public void surfaceDestroyed(SurfaceHolder arg0) {
		//退出时结束线程
		runFlag = false;		
	}
	
	//重写run方法
	@Override
	public void run() {
		int x = 0;
		int y = 0;
		int dx = 2;
		int dy = 3;
		int width = 30;
		int height = 30;
		while(runFlag){
			Canvas canvas = null;
			try {
				//锁定画笔对象
				canvas = holder.lockCanvas();
				//设置画笔
				paint.setColor(Color.WHITE);
				paint.setStyle(Paint.Style.FILL);
				//填充背景颜色
				Rect rect = new Rect(0, 0, this.getWidth(), this.getHeight());
				canvas.drawRect(rect, paint);
				
				//绘制小球,设置小球颜色为红
				paint.setColor(Color.RED);
				RectF rf = new RectF(x, y, x+width, y+height);
				canvas.drawOval(rf, paint);
				
				//小球移动
				x += dx;
				y += dy;
				//边界判断
				if(x<=0 || x>=this.getWidth()){
					dx = -dx;
				}
				if(y<=0 || y>=this.getHeight()){
					dy = -dy;
				}

				Thread.sleep(40);
				
			} catch (InterruptedException e) {
				e.printStackTrace();
			}finally{
				//画布用完要释放
				if(canvas != null){
					holder.unlockCanvasAndPost(canvas);
				}
			}			
		}		
	}
}




 

 
Android 简单动画中SurfaceView 的应用