使用支架和单独的线程在画布上绘图不会在屏幕上显示任何内容

时间:2014-01-10 11:13:24

标签: java android android-canvas surfaceview

我想使用带有“粘性”画布的SurfaceView。即一个保留其状态但未获得验证的。我按照一个例子展示了如何设置一个支架并使用一个单独的线程进行绘图。我们的想法是,当触摸SurfaceView上的任何地方时,如果给出一些颜色,将调用drawStuff,并且应绘制一个随机矩形。

虽然代码执行完美,但最后没有绘制任何内容。

public class DrawingView extends SurfaceView implements Callback {

    Paint currentPaint;
    float verts[];
    private Boolean drawing = false;

    class DrawingThread extends Thread {
        private SurfaceHolder surfaceHolder;
        private SurfaceView surfaceView;
        private Boolean isRunning = false;

        public void setIsRunning(Boolean isRunning) {
            this.isRunning = isRunning;
        }

        public DrawingThread(SurfaceHolder surfaceHolder, SurfaceView surfaceView) {
            super();
            this.surfaceHolder = surfaceHolder;
            this.surfaceView = surfaceView;
        }


        @Override
        public void run() {
            while(isRunning) {
                Canvas c = surfaceHolder.lockCanvas();
                surfaceView.draw(c);
                surfaceHolder.unlockCanvasAndPost(c);
            }
        }
    }

    DrawingThread thread;


    public DrawingView(Context context) {
        super(context);
        this.setWillNotDraw(false);
        this.setBackgroundColor(Color.WHITE);

        this.getHolder().addCallback(this);
        this.thread = new DrawingThread(getHolder(), this);
    }

    @Override
    protected void onDraw(Canvas canvas) {

        if (drawing) {
            // TEST CODE. WILL NEVER USE THIS IN PRODUCTION
            canvas.drawRect(new Rect(new Float(Math.random()*200).intValue(), 20, new Float(Math.random()*200).intValue(), 30), currentPaint);
            drawing = false;
        }

    }


    public void drawStuff(Paint paint) {
        currentPaint = paint;

        drawing = true;
    }

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

    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        thread.setIsRunning(true);
        thread.start();
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        thread.setIsRunning(false);

    }


}

和油漆设置:

view.setOnTouchListener(new View.OnTouchListener() {

    @Override
    public boolean onTouch(View v, MotionEvent event) {

        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setStyle(Paint.Style.FILL);
        paint.setColor(Color.BLUE);
        paint.setAlpha(55);

        ((DrawingView) v).drawStuff(paint);

        //v.invalidate();

        return false;
    }
});

1 个答案:

答案 0 :(得分:0)

最后,当你认为自己时,你实际上并没有画画。调用draw()会在您的UI线程上安排绘制,但实际上并未从您的后台线程调用onDraw,因此您的Canvas不再对表面有效。您应该将正在执行的操作渲染到Bitmap对象中,并且当您准备写入曲面时,请通知UI线程。然后,UI线程可以锁定曲面,将位图绘制到Canvas,然后解锁并将Canvas发布到曲面。