Activity的onBackPressed方法从未被调用。

3
我正在尝试在我的应用程序中拦截返回按钮事件以实现一些自定义功能,但是我在相关回调中编写的任何内容都没有被执行,而且我无法理解原因。以下是我重写的方法:
@Override
public void onBackPressed() {
    super.onBackPressed();

    Log.e(LOG_TAG, "Back pressed");

    if (isMainScreenShowing) {
        finish();
    } else if (isTopLevelScreenShowing){
        loadNewScreen(new AccountBalanceInfoFragment());
    }
}

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    Log.e(LOG_TAG, "Key down = " + keyCode);
    return super.onKeyDown(keyCode, event);
}

@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
    Log.e(LOG_TAG, "Key up = " + keyCode);
    return super.onKeyDown(keyCode, event);
}

如果有关系的话,我正在将这个放在一个扩展SherlockFragmentActivity in ActionBarSherlock的活动中。返回按钮仍然可以弹出前一个片段事务,但我无法实现自己的自定义功能。
更新:当点击返回按钮时,我注意到以下logcat输出:
10-01 16:42:49.879: D/InputEventConsistencyVerifier(7597): KeyEvent: ACTION_UP but key was not down.` 
10-01 16:42:49.879: D/InputEventConsistencyVerifier(7597):   in com.android.internal.policy.impl.PhoneWindow$DecorView{40cd4198 V.E..... R.....I. 0,0-480,800}
10-01 16:42:49.879: D/InputEventConsistencyVerifier(7597):   0: sent at 68941888000000, KeyEvent { action=ACTION_UP, keyCode=KEYCODE_BACK, scanCode=158, metaState=0, flags=0x8, repeatCount=0, eventTime=68941888, downTime=68941823, deviceId=0, source=0x101 }

目前有一些原因导致按键事件无法正确处理... 这仍然是一个谜团。

更新2: 我应该把我对SBerg答案的回应也复制在这里,因为它是相关的 -

我注意到onKeyUp回调现在似乎是工作的。我还不确定我现在做了什么不同。但是,KeyDown和OnBackPressed仍然没有被调用,这非常奇怪,但是现在KeyUp似乎足够解决问题了。

@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_BACK) {
        Log.i(LOG_TAG, "Back pressed");
        // do stuff here
    }
    return super.onKeyUp(keyCode, event);
}

目前这是一个适合的解决方法,但它有点混乱,而且仍然希望了解为什么第一个onBackPressed和onKeyDown回调函数没有被调用。


请查看我的答案。它应该有效。 - superuser
请查看我的答案是否正确 - superuser
1
不确定这是否会导致您的问题,但您不应该从onKeyUp()调用super.onKeyDown() - Geobits
哈哈,发现得好。这是我的一个小疏忽。这可能至少解决了一个谜团(为什么默认的键盘抬起行为没有被执行),但其他回调函数仍未被调用。 - RocketGuy3
3个回答

4
你需要让 onKeyDownPress 在返回之前判断是否为后退键,如果是就要返回 true。下面是实现方式。如果没有返回 true,触摸事件将不会被传递
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    Log.e(LOG_TAG, "Key down = " + keyCode);
    if(keyCode == KeyEvent.KEYCODE_BACK){
        return true;
    }else{
    return super.onKeyDown(keyCode, event);
    }
}

我明天早上才能真正测试这个,但老实说我有点怀疑它是否有效。在我发的代码中,即使控制台日志也从未打印过,因此我的回调根本没有被调用。我不确定为什么添加你这里的代码会改变这一点。 - RocketGuy3
是的,那是不行的。我刚刚更新了我的帖子,并提供了更多关于问题的信息。谢天谢地,我找到了这个 keyUp 解决方法,但它有点凌乱,而且这仍然是一个非常奇怪的问题。 - RocketGuy3
1
您能解释一下为什么您的回答似乎与文档相矛盾,尽管它似乎有效吗?从文档上看: “返回true以防止进一步传播此事件,或返回false以表示您未处理此事件并且应继续传播。” 您似乎在暗示完全相反的事情,并且您似乎是正确的。文档有误还是我理解有误? - matteo

0
backButtonRl.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                getActivity().onBackPressed();
            }
        });

0
我想把这个放到答案里,这样更容易找到:
我注意到 onKeyUp 回调现在似乎正在工作。我还不确定我现在做了什么不同。然而,按下键和返回键仍然没有被调用,这非常奇怪,但是现在看来按键弹起已经足够解决问题了。
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_BACK) {
        Log.i(LOG_TAG, "Back pressed");
        // do stuff here
    }
    return super.onKeyUp(keyCode, event);
}

这是一个暂时适合的解决方案,但它有些混乱,并且仍然很想知道为什么第一个onBackPressed和onKeyDown回调未被调用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接