黑莓java检测屏幕前景事件

时间:2011-06-24 15:40:48

标签: blackberry java-me

在我的BlackBerry应用程序中,我有一个主屏幕。然后,用户可以导航到设置屏幕。当用户返回主屏幕时,是否在主屏幕上没有调用方法指示屏幕已到达前台?

我试过onFocus()但没有用。

谢谢!

2 个答案:

答案 0 :(得分:4)

不幸的是,挂钩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:如果您有一个固定大小的输入字段,并且在用户完成后按下新屏幕,如果用户键入,您当前的屏幕将不会收到通知很快。发生这种情况是因为在您调用push(newScreen)之间的那一刻,实际上是用户点击了软KB上的字母,它抓住焦点。因此,只调用onObscured,而不调用onCovered

解决方案:push(newScreen)

之前明确隐藏了软键盘

示例B:如果您有一个自定义对话框,该对话框会推送新屏幕然后自行解除,则您当前的屏幕将不会收到通知。发生这种情况是因为您的自定义对话框未被识别为屏幕,因此仅调用onObscured,而不调用onCovered

解决方案:首先关闭对话框,返回结果值,让屏幕根据该值推送新屏幕。 - 或者 - 覆盖isMyAppScreen()以便为您的自定义对话框返回true

答案 1 :(得分:3)

您应该可以使用protected void onExposed()来检测它何时再次显示。

相关问题