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中实现动画效果的方法有很多种,这里我们演示一种简单的方法:使用ThreadHandler来更新界面。

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