BlackBerry Java, обнаруживающий событие на переднем плане экрана - PullRequest
3 голосов
/ 24 июня 2011

В моем приложении BlackBerry у меня есть домашний экран.Затем пользователь может перейти к экрану настроек.Когда пользователь возвращается к начальному экрану, нет ли метода, который вызывается на главном экране, указывающего, что экран вышел на передний план?

Я пробовал onFocus () безрезультатно.

Спасибо!

Ответы [ 2 ]

4 голосов
/ 20 июля 2011

К сожалению, перехватить onExposed недостаточно. Я обнаружил, что в Blackberry диалоги также являются экранами и даже контекстные меню тоже являются экранами. Они помещаются в верхней части экрана, поэтому вы получаете обратный вызов onExposed при их отклонении.

Хотя во многих случаях все нормально, в других случаях возникает проблема - например, если я должен обновлять содержимое экрана только тогда, когда пользователь возвращается к нему, но не после меню / диалогов, то как мне это сделать? Мой случай, к сожалению, один из них.

Я не нашел документированного способа обнаружения «покрытых» / «непокрытых» событий. Вот мой подход. onCovered / onUncovered обратные вызовы вызываются, когда текущий экран покрывается / открывается другим экраном приложения, но не диалоговыми окнами / меню / виртуальной клавиатурой:

public class MyAppScreen extends MainScreen {
    private boolean isCovered;

    protected void onExposed() {
        Log.d("onExposed");
        super.onExposed();
        if (isCovered) {
            onUncovered();
            isCovered = false;
        }
    }

    protected void onObscured() {
        Log.d("onObscured");
        super.onObscured();
        final Screen above = getScreenAbove();
        if (above != null) {
            if (isMyAppScreen(above)) {
                isCovered = true;
                onCovered();
            }
        }
    }

    private boolean isMyAppScreen(final Screen above) {
        return (above instanceof MyAppScreen);
    }

    protected void onUncovered() {
        Log.d("onUncovered");
    }

    protected void onCovered() {
        Log.d("onCovered");
    }

    protected void onUiEngineAttached(final boolean attached) {
        if (attached) {
            Log.d("UI Engine ATTACHED");
        } else {
            Log.d("UI Engine DETACHED");
        }
        super.onUiEngineAttached(attached);
    }

    protected void onFocusNotify(final boolean focus) {
        if(focus){
            Log.d("focus GAINED");
        } else {
            Log.d("focus LOST");
        }
        super.onFocusNotify(focus);
    }
}

И тест. Попробуйте различные комбинации и посмотрите, какие события вы получите в журнале.

public class TestLifecycle extends MyAppScreen implements FieldChangeListener {
    private final ABNTextEdit txt1;
    private final ButtonField btn1;
    private final ButtonField btn2;

    public TestLifecycle() {

        final Manager manager = getMainManager();

        txt1 = new ABNTextEdit();
        manager.add(txt1);

        btn1 = new ButtonField("Dialog", ButtonField.CONSUME_CLICK);
        btn1.setChangeListener(this);
        manager.add(btn1);

        btn2 = new ButtonField("Screen", ButtonField.CONSUME_CLICK);
        btn2.setChangeListener(this);
        manager.add(btn2);
    }

    public void fieldChanged(final Field field, final int context) {
        if (field == btn1) {
            Dialog.alert("Example alert");
        } else if (field == btn2) {
            UiApplication.getUiApplication().pushScreen(new TestLifecycle());
        }
    }
}

Обновление:

Этот метод имеет ограничение: если новый экран нажимается, когда диалоговое окно или программная клавиатура находится в фокусе, ваш текущий экран будет не получать onCovered / onUncovered уведомление.

Пример A: если у вас есть поле ввода фиксированного размера, и вы нажимаете новый экран, когда пользователь завершает его, ваш текущий экран не будет получать уведомление, если пользователь введет very быстро. Это происходит потому, что в тот момент, когда вы звоните push(newScreen) и он фактически нажимается, пользователь нажимает на букву в мягкой КБ, и он захватывает фокус. Так называется только onObscured, но не onCovered.

Решение: явно скрыть программную клавиатуру до push(newScreen).

Пример B: Если у вас есть настроенное диалоговое окно, которое открывает новый экран, а затем закрывает себя, ваш текущий экран не получит уведомление. Это происходит потому, что ваш настроенный диалог не распознается как экран, поэтому вызывается только onObscured, но не onCovered.

Решение: в первую очередь закрывает диалоговое окно, возвращающее значение результата, и позволяет вашему экрану выдвигать новый экран на основе этого значения. -ИЛИ- переопределить isMyAppScreen() для возврата true также для настраиваемого диалогового окна.

3 голосов
/ 24 июня 2011

Вы должны быть в состоянии использовать protected void onExposed(), чтобы определить, когда оно отображается снова.

...