使用SurfaceView绘图

SurfaceView的介绍:

我们可以自定义View,重写onDraw利用canvas进行绘图。但是,onDraw不能执行太耗时的操作,View是通过刷新来重绘视图的,刷新的间隔是16ms,所以在16ms要执行完绘图操作,不然就会出现卡顿。为了解决这一问题,Android提供了SurfaceView来解决这个问题。它与View的区别主要有以下几点:

  • View是在主线程中对画面进行刷新,而Surface通常会通过一个子线程来进行页面的刷新。
  • View在绘图时没有使用双缓冲机制,而SurfaceView在低层实现机制中就已经实现了双缓冲机制。
  • View主要适用于主动更新的情况下,而SurfaceView主要适用于被动更新。
所以呢,如果你的View需要频繁刷新的话,或者刷新时数据处理量比较大,就可以考虑选用SurfaceView来处理。

SurfaceView的一般使用方法:
1、自定义一个子类继承Surface,并实现两个接口,即SurfaceView.Callback和Runnable,并且实现这两个接口的方法。代:码如下
public class MyView extends SurfaceView implemnts SurfaceHolder,Runnable
{
<span style="white-space:pre">	</span>@Override
<span style="white-space:pre">	</span>public void surfaceCreated(SurfaceHolder holder)
<span style="white-space:pre">	</span>{}
<span style="white-space:pre">	</span>@Override
<span style="white-space:pre">	</span>public void surfaceChanged(SurfaceHolder holder,int format,int width,int height)
<span style="white-space:pre">	</span>{}
<span style="white-space:pre">	</span>@Override
<span style="white-space:pre">	</span>public void surfaceDestroyed(SurfaceHolder holder)
<span style="white-space:pre">	</span>{}
<span style="white-space:pre">	</span>
<span style="white-space:pre">	</span>@Override
<span style="white-space:pre">	</span>public void run()
<span style="white-space:pre">	</span>{}
}
前三个方法分别是于Surface的创建、创建和销毁的回调方法,最后一个run方法是实现Runnable接口的。

2、初始化SurfaceView
通常要设置这样三个成员变量,代码如下:
//SurfaceHolder,主线程的Holder,用来实现回调
private SurfaceHolder mHolder;
//用来绘图的Canvas
private Canvas mCanvas;
//子线程的标志位
private boolean mIsDrawing;
mHolder是获取主线程的Holder,用来实现SurfaceHolder.Callback的回调。mCanvas就是像View一样,用来绘图的。最后mIsDrawing来标志子线程何时结束绘图。

3、使用SurfaceView。
可以通过SurfaceView的lockCanvas方法,可以获取得到当前Canvas的绘图对象。注意,获取的Canvas对象还是以前的Canvas对象,不是新的一个对象,还是会保存着之前的绘图操作,如果需要去除之前的绘图操作,通过drawColor()方法来进行清屏操作。

下面就是SurfaceView的使用例子代码:
public class MyView extends SurfaceView implemnts SurfaceHolder,Runnable
{
	//SurfaceHolder
	private SurfaceHolder mHolder;
	//用来绘图的Canvas
	private Canvas mCanvas;
	//子线程的标志位
	private boolean mIsDrawing
	
	public MyView(Context context)
	{
		super(context);
		initView();
	}
	
	public MyView(Context context,AttributeSet attrs)
	{
		super(context,attrs);
		initView();
	}
	
	public SurfaceView(Context context,AttributeSet attrs,int defStyle)
	{
		super(context,attrs,defStyle);
		initView();
	}
	
	private void initView()
	{
		mHolder = getHolder();
		mHolder.addCallback(this);
		this.setKeepScreenOn(true);
	
	}

	@Override
	public void surfaceCreated(SurfaceHolder holder)
	{
		mIsDrawing = true;
		new Thread(this).start();
	}
	@Override
	public void surfaceChanged(SurfaceHolder holder,int format,int width,int height)
	{}
	@Override
	public void surfaceDestroyed(SurfaceHolder holder)
	{
		mIsDrawing = false;
	}
	
	@Override
	public void run()
	{
		while(mIsDrawing)
		{
			try{
				mCanvas = mHolder.lockCanvas();
				draw(mCanvas);
			}
			catch(Exception e){
			}
			finally{
				if(mCanvas != null)
				{
					mHolder.unlockCanvasAndPost(mCanvas);
				}
			}
		}
	}
	
	private void draw(Canvas canvas)
	{
		//执行自己的绘图操作。
	}
	
	
}






猜你喜欢

转载自blog.csdn.net/u014686721/article/details/52289536