Android开发--SurfaceView的基本用法

本文详细记录了如何在Android中使用SurfaceView替代View来实现多线程绘图和双缓冲技术,从而使得动画更加流畅。包括SurfaceView的生命周期管理、异步线程绘图操作及关键代码实现。

        在Android中可以利用View来绘制一些图形,图片,但当我们开发游戏或视频时,View就不再适用,这时必须使用SurfaceView来代替View。SurfaceView相比View可以实现多线程绘图和双缓冲技术,可以使得我们的动画更加流畅。接下来简单记录一下Surface的基本用法:

        首先我们应该继承SurfaceView的类,并实现SurfaceHolder.Callback,这个接口是用来管理SurfaceView的生命周期,一共有三个方法:

             1)surfaceCreated: SurfaceView对象被创建时触发;
             2)surfaceChanged: SurfaceView的大小发生变化时触发;
             3)surfaceDestroyed: SurfaceView对象被销毁时触发;

         我们在初始化方法中得到SurfaceHolder的对象,并通过该对象的addCallback方法添加这个接口进来

        private void init() {
		holder = getHolder();
		holder.addCallback(this);
		paint = new Paint();
		paint.setColor(Color.BLUE);
		paint.setStyle(Paint.Style.STROKE);
	}
          接下来创建我们的异步线程来进行绘图操作
	private Thread myThread = new Thread(new Runnable() {

		@Override
		public void run() {
			// TODO Auto-generated method stub
			while (isLived) {
				if (num <= 20) {
					num++;
				} else {
					num = 2;
				}
				canvas = holder.lockCanvas();
				if (canvas != null) {
					canvas.drawColor(Color.BLACK);//清屏
					canvas.drawCircle(100, 100, num, paint);
					holder.unlockCanvasAndPost(canvas);
				}
				try {
					Thread.sleep(1000);
				} catch (Exception e) {
					// TODO: handle exception
				}
			}
		}
	});
        通过lockCanvas方法我们可以得到一个加锁的Canvas,当Canvas在进行绘图时,或被锁起来。注:如果当前Canvas正在被绘制,将会返回一个null值。接下来我们绘制一个空心的圆,半径不断增加。绘制完成后将锁打开。


         然后我们在Callback接口方法中在create方法中设置标志isLived为true,然后开启线程,在destory方法中设置isLived为false

	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width,
			int height) {
		// TODO Auto-generated method stub

	}

	@Override
	public void surfaceCreated(SurfaceHolder holder) {
		// TODO Auto-generated method stub
		isLived = true;
		myThread.start();
		Log.w(TAG, "surfaceCreated");
	}

	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {
		// TODO Auto-generated method stub
		isLived = false;
		Log.w(TAG, "surfaceDestroyed");
	}

附上整个类的源码
package com.example.test;

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

public class MySurfaceView extends SurfaceView implements
		SurfaceHolder.Callback {

	private static final String TAG = "MySurfaceView";

	private SurfaceHolder holder;
	private boolean isLived;
	private Paint paint;
	private Canvas canvas;
	private int num;
	private Thread myThread = new Thread(new Runnable() {

		@Override
		public void run() {
			// TODO Auto-generated method stub
			while (isLived) {
				if (num <= 20) {
					num++;
				} else {
					num = 2;
				}
				canvas = holder.lockCanvas();
				if (canvas != null) {
					canvas.drawColor(Color.BLACK);
					canvas.drawCircle(100, 100, num, paint);
					holder.unlockCanvasAndPost(canvas);
				}
				try {
					Thread.sleep(1000);
				} catch (Exception e) {
					// TODO: handle exception
				}
			}
		}
	});

	public MySurfaceView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		// TODO Auto-generated constructor stub
		init();
	}

	public MySurfaceView(Context context, AttributeSet attrs) {
		super(context, attrs);
		// TODO Auto-generated constructor stub
		init();
	}

	public MySurfaceView(Context context) {
		super(context);
		init();
		// TODO Auto-generated constructor stub
	}

	private void init() {
		holder = getHolder();
		holder.addCallback(this);
		paint = new Paint();
		paint.setColor(Color.BLUE);
		paint.setStyle(Paint.Style.STROKE);
	}

	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width,
			int height) {
		// TODO Auto-generated method stub

	}

	@Override
	public void surfaceCreated(SurfaceHolder holder) {
		// TODO Auto-generated method stub
		isLived = true;
		myThread.start();
		Log.w(TAG, "surfaceCreated");
	}

	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {
		// TODO Auto-generated method stub
		isLived = false;
		Log.w(TAG, "surfaceDestroyed");
	}

}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值