Android SurfaceView自定义View
简介
在Android中,我们可以通过自定义View来实现各种各样的用户界面效果。其中,SurfaceView是一种特殊的View,它可以在一个单独的线程中进行绘图操作。相比于普通的View,SurfaceView可以更高效地实现动画效果,因为它可以在后台线程中进行绘图操作,不会阻塞UI线程。
本文将介绍如何使用SurfaceView来自定义View,并提供代码示例。
创建自定义View
首先,我们需要创建一个继承自SurfaceView的类,用于实现自定义的绘图逻辑。在这个类中,我们可以重写SurfaceView的一些方法,例如onDraw()
用于绘制图形。
public class MySurfaceView extends SurfaceView {
private SurfaceHolder mSurfaceHolder;
public MySurfaceView(Context context) {
super(context);
init();
}
public MySurfaceView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public MySurfaceView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
mSurfaceHolder = getHolder();
mSurfaceHolder.addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(SurfaceHolder holder) {
// SurfaceView创建时的回调方法
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
// SurfaceView尺寸改变时的回调方法
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// SurfaceView销毁时的回调方法
}
});
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 在这里进行绘图操作
}
}
在init()
方法中,我们获取了SurfaceHolder对象,并通过addCallback()
方法注册了一个SurfaceHolder的回调,用于监听SurfaceView的创建、尺寸改变和销毁事件。
在onDraw()
方法中,我们可以通过传入的Canvas
对象进行绘图操作。可以使用Canvas提供的各种绘制方法,例如绘制图形、绘制文本等。关于绘图的详细内容可以参考[Android绘图API文档](
绘制图形
接下来,我们将演示如何在自定义的SurfaceView中绘制一个简单的图形。
public class MySurfaceView extends SurfaceView {
// ...
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 清空画布
canvas.drawColor(Color.WHITE);
// 绘制一个圆形
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setColor(Color.RED);
int centerX = getWidth() / 2;
int centerY = getHeight() / 2;
int radius = Math.min(centerX, centerY);
canvas.drawCircle(centerX, centerY, radius, paint);
}
}
在上述代码中,我们首先通过canvas.drawColor(Color.WHITE)
方法将画布填充为白色。然后,我们创建一个Paint
对象,并设置其属性,例如抗锯齿、颜色等。接着,我们计算出圆形的中心点和半径,并使用canvas.drawCircle()
方法来绘制圆形。
动画效果
在SurfaceView中实现动画效果的方法有很多种,这里我们演示一种简单的方法:使用Thread
和Handler
来更新界面。
public class MySurfaceView extends SurfaceView implements Runnable {
// ...
private Thread mRenderThread;
private boolean mRunning;
private Handler mHandler;
public MySurfaceView(Context context) {
super(context);
init();
}
private void init() {
// ...
mHandler = new Handler(Looper.getMainLooper());
}
public void startAnimation() {
mRunning = true;
mRenderThread = new Thread(this);
mRenderThread.start();
}
public void stopAnimation() {
mRunning = false;
try {
mRenderThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public void run() {
while (mRunning) {
Canvas canvas = null;
try {
canvas = mSurfaceHolder.lockCanvas();
if (canvas != null) {
synchronized (m