SurfaceView обновляет пользовательский интерфейс только один раз

Я пытался научиться использовать SurfaceView, так как мне нужно использовать его в будущем проекте. Я читал, что если мне нужно быстро обновить пользовательский интерфейс, предпочтительнее использовать 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. Но когда я выполняю код, активность остается на несколько секунд с пустым экраном, а после этого круги появляются на растровом изображении. но не чередует последовательность, хотя поток вроде запущен. Рисуются только последние 8 элементов тестового массива.

Похоже, вы рисуете все растровые изображения одновременно x. И непонятно, почему вы ожидаете, что «последовательность будет чередоваться»; testTransition() выполняет одну и ту же функцию при каждом вызове: она никак не параметризуется, и вы не продвигаете состояние каких-либо переменных-членов.

greeble31 25.07.2019 19:19

@ greeble31 Да, x такой же, когда появятся еще 8 элементов, я хочу перерисовать следующие 8 элементов. X то же самое, потому что я хочу сделать эффект POV.

Oscar Moncayo 25.07.2019 19:22

ваш цикл while выполняется более одного раза? обновляется ли объект из test[]? вы отлаживали и видели, что не происходит

Marcos Vasconcelos 25.07.2019 19:47

Обычно у вас есть два шага: 1) обработка ввода и изменение фоновых данных test[] 2) рисование экрана; повторить

Marcos Vasconcelos 25.07.2019 19:49

Кроме того: ваш testTransition блокирует отрисовку, вы увидите результат только ПОСЛЕ завершения метода (и задержка (1000);) заблокирует его время, и вы рисуете все состояния одним и тем же методом, будет показано последнее, оба предложения рано могут решить проблему

Marcos Vasconcelos 25.07.2019 19:51

Спасибо @MarcosVasconcelos, я попробую ваше предложение :)

Oscar Moncayo 25.07.2019 20:08

@MarcosVasconcelos Благодаря вашей помощи я смог перейти к ответу. БОЛЬШОЕ СПАСИБО! :D

Oscar Moncayo 25.07.2019 20:15
0
7
44
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

С SurfaceView и lockCanvas() экран не сможет обновиться, пока после вы не позвоните unlockCanvasAndPost(). (Я думаю, вы ожидали, что экран обновится в середине testTransition().)

Решение состоит в том, чтобы реализовать конечный автомат, который загрязняет SurfaceView на основе таймера (например) и продвигает светодиодный дисплей на одну строку на каждой итерации.

Другие вопросы по теме