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

被折叠的 条评论
为什么被折叠?



