SurfaceView是Android系统提供的另一种绘图处理的方案(还有一种是view)。SurfaceView与View是一对孪生兄弟,那他们有什么区别呢?
1.View主要适用于主动更新的情况下,而SurfaceView主要适用于被动更新,例如频繁刷新
2.View在主线程中对画面进行刷新,而SurfaceView通常会通过一个子线程来更新页面刷新
3.View在绘图时没有适用双缓冲机制,而SurfaceView在底层实现机制中已经实现了双缓冲机制。
如果你的自定义view需要频繁刷新,或者刷新时数据处理量比较大,那就考虑适用surfaceview来替代view。
使用SurfaceView有自己一套模板代码:
public class SurfaceViewTemplate extends SurfaceView implements SurfaceHolder.Callback,Runnable{
//模板中必须的
private SurfaceHolder mHolder;
private Canvas mCanvas;//用于绘图的canvas
private boolean isDrawing;//子线程是否继续的标志
public SurfaceViewTemplate(Context context) {
super(context);
init();
}
public SurfaceViewTemplate(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public SurfaceViewTemplate(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init(){
mHolder = getHolder();
mHolder.addCallback(this);
setFocusable(true);
setFocusableInTouchMode(true);
setKeepScreenOn(true);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
isDrawing = true;
new Thread(this).start();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
isDrawing = false;
}
@Override
public void run() {
while (isDrawing){
draw();
}
}
//真正工作的方法
private void draw(){
try {
mCanvas = mHolder.lockCanvas();
//干活的地方
}catch (Exception e){
}finally {
if (mCanvas!=null)
mHolder.unlockCanvasAndPost(mCanvas);
}
}
}
正弦曲线效果:
public class SurfaceViewTemplate extends SurfaceView implements SurfaceHolder.Callback,Runnable{
//模板中必须的
private SurfaceHolder mHolder;
private Canvas mCanvas;//用于绘图的canvas
private boolean isDrawing;//子线程是否继续的标志
//例子中需要
private Path mPath;
private Paint mPaint;
private int x,y=400;
public SurfaceViewTemplate(Context context) {
super(context);
init();
}
public SurfaceViewTemplate(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public SurfaceViewTemplate(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init(){
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setColor(Color.BLACK);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(5);
mPath = new Path();
mPath.moveTo(x,y);
mHolder = getHolder();
mHolder.addCallback(this);
setFocusable(true);
setFocusableInTouchMode(true);
setKeepScreenOn(true);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
isDrawing = true;
new Thread(this).start();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
isDrawing = false;
}
@Override
public void run() {
while (isDrawing){
draw();
x += 1;
y = (int)(100*Math.sin(x*2*Math.PI/180)+400);
mPath.lineTo(x,y);
}
}
//真正工作的方法
private void draw(){
try {
mCanvas = mHolder.lockCanvas();
//干活的地方
mCanvas.drawColor(Color.WHITE);//背景
mCanvas.drawPath(mPath,mPaint);
}catch (Exception e){
}finally {
if (mCanvas!=null)
mHolder.unlockCanvasAndPost(mCanvas);
}
}
}