SurfaceView 只更新 UI 一次

SurfaceView only update UI once

我正在尝试学习如何使用 SurfaceView,因为我需要在未来的项目中使用它。我读到如果我需要快速更新 UI,最好在线程的帮助下使用 SurfaceView。

我的代码的目的是能够在位图上打印一个'B'的图案,这里是代码:

public void testTransition(Canvas canvas) {
    if (canvas != null) {
        canvas.drawColor(Color.BLACK);
        Log.i("Thread", "Running...");
        for (int y = 0; y < 8; y++) {
            if (test[y] == 1) {

                canvas.drawBitmap(ledBitMap, (x - diameterLeds) / 2, diameterLeds * y, paint);

            }

        }


        canvas.drawColor(Color.BLACK);
        delay(1000);

        for (int y=0; y<8; y++){
            if(test[y + 8] == 1)
                canvas.drawBitmap(ledBitMap, (x - diameterLeds) / 2,diameterLeds * y, paint);

        }
        canvas.drawColor(Color.BLACK);
        //ledThread.delay(1000);


        for (int y=0; y<8; y++){
            if(test[y + 16] == 1)
                canvas.drawBitmap(ledBitMap, (x- diameterLeds) / 2,diameterLeds * y, paint);

        }
        canvas.drawColor(Color.BLACK);
        //ledThread.delay(1000);

        for (int y=0; y<8; y++){
            if(test[y + 24] == 1)
                canvas.drawBitmap(ledBitMap, (x - diameterLeds) / 2,diameterLeds * y, paint);

        }
        canvas.drawColor(Color.BLACK);
        //ledThread.delay(1000);

        for (int y=0; y<8; y++){
            if(test[y + 32] == 1)
                canvas.drawBitmap(ledBitMap, (x - diameterLeds) / 2,diameterLeds * y, paint);

        }

        //canvas.drawColor(Color.BLACK);



        //ledThread.delay(600);

        //delay(1);
    }
}


@Override
public void run() {
    long ticksPS = 1000 / 30;
    long startTime;
    long sleepTime;

    while(isRunning){

        Canvas canvas = null;
        startTime = System.currentTimeMillis();

        try {
            canvas = ledView.getHolder().lockCanvas();
            synchronized (ledView.getHolder()){
                testTransition(canvas);
            }
        }finally {
           if(canvas != null){
               ledView.getHolder().unlockCanvasAndPost(canvas);
           }
        }
    }
}

变量test[]是一个包含40个元素(0或1)的矩阵

private static int test[] = {1,1,1,1,1,1,1,1, 1,0,0,1,0,0,0,1, 1,0,0,1,0,0,0,1, 1,0,0,1,0,0,0,1, 0,1,1,0,1,1,1,0};

我的目标是阅读此排列并模拟字母 B 的模式 'on or off'。但是当我执行代码时,activity 会在黑屏中停留几秒钟,并且之后,圆圈出现在位图上,但不会改变顺序,尽管线程似乎是 运行。只绘制了测试数组的最后8个元素

对于 SurfaceViewlockCanvas(),屏幕无法更新,直到 在您调用 unlockCanvasAndPost() 之后。 (我认为您希望屏幕在 testTransition() 中途更新。)

解决方案是实现一个状态机,它基于计时器(例如)弄脏 SurfaceView,并在每次迭代时将 LED 显示前进一行。