Метод активности Android, чтобы дисплей мигал белым для предупреждения

Я пытаюсь заставить андроид мигать как предупреждение пользователю (весь экран). Чтобы заставить его мигать, я вставил ImageView в действие, равное размеру дисплея и белому цвету, который изменит его видимость с видимого на исчезнувший. Я изучал возможность создания внешнего потока, но позже обнаружил, что внешние потоки не могут изменять компоненты пользовательского интерфейса. Мне нужно приостановить поток между изменениями флэш-памяти, что означает, что я не смогу поместить его в основной поток пользовательского интерфейса. Как мне реализовать что-то подобное?

Я добавил часть своего кода ниже:

XML

<ImageView
        android:id = "@+id/alertScreen"
        android:layout_width = "match_parent"
        android:layout_height = "match_parent"
        android:visibility = "gone"
        app:srcCompat = "@android:color/white" />

Main.java

    public static boolean flashOn = false;
    public static boolean endFlash = false;
    public static Context context;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.aircraft_main);
        AircraftMain.context = getApplicationContext();

        flash = (Button) findViewById(R.id.flashTest);
        flash.setOnClickListener(flashBtnOnClickListener);
    }

    View.OnClickListener flashBtnOnClickListener = new View.OnClickListener() {
        @Override
        public void onClick(View arg0) {

            AsyncTask.execute(new Runnable() {
                public void run(){
                    AlertFlash alert = new AlertFlash(3);
                    alert.run();

                    ImageView v = findViewById(R.id.alertScreen);

                    while (endFlash != true) {
                        if (flashOn = true) {
                            v.setVisibility(View.VISIBLE);
                        } else {
                            v.setVisibility(View.GONE);
                        }
                    }
                }
            });

        }
    };

AlertFlash.java

public class AlertFlash implements Runnable {

    public static volatile int flashes;
    boolean suspendFlag, end;

    public AlertFlash (int flashNo) {
        flashes = flashNo * 2;
        suspendFlag = false;
        end = false;
    }

    public void run() {
        for (int i = 0; i<=flashes; i++) {

            if (suspendFlag = false) {
                AircraftMain.flashOn = true;
                suspendFlag = true;
            }
            else {
                AircraftMain.flashOn = false;
                suspendFlag = false;
            }

            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
        end = true;
    }
}
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
0
142
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Используя Activity.runOnUiThread(), вы можете изменять элементы пользовательского интерфейса из фонового потока.

Вот как я бы поступил в вашей ситуации. Внутри Main.java я бы начал с создания простого метода для изменения видимости переданного представления, особенно в потоке пользовательского интерфейса:

private void setViewVisibility(final View view, final int visibility) {
    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            view.setVisibility(visibility);
        }
    });
}

Затем я бы изменил цикл while на следующий:

while (endFlash != true) {
    if (flashOn = true) {
        setViewVisibility(v, View.VISIBLE);
    } else {
        setViewVisibility(v, View.GONE);
    }
}

Обновлено:, чтобы предотвратить проблемы с циклом while, мы можем полностью обойти его, передав activity и view при создании объекта AlertFlash. См. ниже.

public class AlertFlash implements Runnable {

    public static volatile int flashes;
    boolean suspendFlag, end;

    private Activity activity;
    private View view;

    public AlertFlash (int flashNo, Activity activity, View view) {
        flashes = flashNo * 2;
        suspendFlag = false;
        end = false;

        this.activity = activity;
        this.view = view;
    }

    public void run() {
        for (int i = 0; i<=flashes; i++) {

            if (suspendFlag = false) {
                AircraftMain.flashOn = true;
                suspendFlag = true;
            }
            else {
                AircraftMain.flashOn = false;
                suspendFlag = false;
            }

            final int visibility = AircraftMain.flashOn ? View.VISIBLE : View.GONE;
            activity.runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    view.setVisibility(visibility);
                }
            });

            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
        end = true;
    }
}

Спасибо. При реализации этого кажется, что только первый результат «мигает», даже если он выполняет полный цикл for. Следует ли переместить цикл while в другое место?

Kieron McAuley-Kinchin 09.03.2018 16:50

Я не могу сказать наверняка по тому, на что я здесь смотрю. Где для endFlash устанавливается значение true?

rjr-apps 09.03.2018 17:05

Я изменил это. В AlertFlash.java я изменил конечное условие на Main.endFlash = true, которое изменяет условие остановки в файле Main.java. Но кажется, что цикл while выполняется только после полного запуска AlertFlash.java. Следовательно, он не выполняет цикл while, потому что было вызвано условие остановки. Куда можно переместить цикл while, чтобы он выполнялся на каждой итерации цикла for AlertFlash.

Kieron McAuley-Kinchin 09.03.2018 17:13

Смотрите мою последнюю правку. Попробуйте передать действие и представление непосредственно в объект AlertFlash, а затем измените видимость представления там. В этом случае цикл while не нужен.

rjr-apps 09.03.2018 22:57

В классе alertflash есть ошибка if (suspendFlag = false) {должно быть if (! SuspendFlag) {

Raymie 11.12.2020 23:37

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