ProgressBar становится видимым после того, как работа сделана - PullRequest
0 голосов
/ 19 октября 2019

Я сделал простое приложение для решения судоку в Android Studio, которое пытается решить любую заданную N x M судоку. Для плат размером 4 x 4 это может занять пару секунд, поэтому я хочу, чтобы неопределенный ProgressBar запускался во время вычислений.

Когда пользователь нажимает кнопку, запускается SolveSudoku(). Сначала он отображает ProgressBar, запускает логику решения, а затем снова скрывает его. Проблема в том, что ProgressBar отображается только после того, как судоку решена и выведена на экран. Как я могу это исправить?

activity_sudoku.xml

<ProgressBar
    android:id="@+id/progressBar"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="parent"
    style="?android:attr/progressBarStyleLarge"
    android:visibility="invisible"
    android:indeterminate="true"
    android:elevation="8dp"/>

SudokuActivity.java

private ProgressBar progBar = findViewById(R.id.progressBar);

public void SolveSudoku(View v){
    progBar.setVisibility(View.VISIBLE);
    try{
        //Solving logic
    }
    catch(Exception ex){
        //Error handling for invalid inputs, etc..
    }
    finally{
        progBar.setVisibility(View.INVISIBLE);
    }
}

Если япрокомментируйте кодовую строку в пункте finally, спиннер просто продолжает вращаться после того, как я получил результат. Но пока что ProgressBar вообще не появляется. Любая помощь приветствуется!

1 Ответ

0 голосов
/ 19 октября 2019

Выбранный вами стиль ProgressBar ?android:attr/progressBarStyleLarge - это блесна.

Если вам нужны и счетчик, и индикатор выполнения, вы должны добавить 2 отдельных представления ProgressBar в xml и стилизовать их по-разному.

Чтобы стилизовать ProgressBar в качестве фактического индикатора выполнения загрузки. , вы можете использовать ?android:attr/progressBarStyleHorizontal

Это пример макета со счетчиком и индикатором выполнения:

    <ProgressBar
        android:id="@+id/spinner_progress_bar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        style="?android:attr/progressBarStyleLarge"
        />

    <ProgressBar
        android:id="@+id/actual_progress_bar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toBottomOf="@id/spinner_progress_bar"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        style="?android:attr/progressBarStyleHorizontal"
        />

Теперь, если вы хотите индикатор выполнения, вы должны обновить его прогрессвручную. Вот пример фрагмента, который обновляет индикатор выполнения с 0 до полного в секунду.

        final ProgressBar progressBar = findViewById(R.id.actual_progress_bar);
        progressBar.setMax(100);

        new Thread(
                () -> {
                    try {
                        int a = 0;
                        while (a <= 100) {
                            final int weakA = a;
                            runOnUiThread(() -> progressBar.setProgress(weakA));
                            a++;
                            Thread.sleep(10);
                        }
                    } catch (InterruptedException e) {

                    }
                }
        ).start();

Идея такова: вы должны самостоятельно рассчитать прогресс вашего алгоритма и установить его соответствующим образом. И не забывайте всегда вызывать ProgressBar.setProgress(int) (или любой конкретный метод представления) в методе runOnUiThread (), иначе вы получите ошибку.

...