是否有一种方法,我们可以实现onBackPressed()在Android片段类似的方式,我们实现在Android活动?

因为Fragment的生命周期没有onBackPressed()。在android3.0片段中是否有其他替代方法来覆盖onBackPressed() ?


当前回答

如果你想要那种功能,你需要在你的活动中覆盖它,然后给你所有的片段添加一个YourBackPressed接口,当你按下后退按钮时,你就会在相关的片段上调用这个接口。

编辑:我想补充我之前的答案。

如果我今天要这样做,我将使用广播,或者如果我希望其他面板同步更新到主/主内容面板,则可能使用有序广播。

支持库中的LocalBroadcastManager可以帮助解决这个问题,你只需要在onBackPressed中发送广播,并在你的片段中订阅。我认为Messaging是一种更加解耦的实现,可伸缩性更好,所以它是我现在的官方实现建议。只要使用Intent的动作作为你信息的过滤器。发送你新创建的ACTION_BACK_PRESSED,从你的活动发送它,并在相关片段中监听它。

其他回答

简单地在onKeyUp()中做:

@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {

    if (keyCode == KeyEvent.KEYCODE_BACK) {
        // do something
        return true;  // return true if back handled, false otherwise
    }

    return super.onKeyUp(keyCode, event);
}

我用这种方式解决了在活动中覆盖onBackPressed。所有的FragmentTransaction在提交前都是addToBackStack:

@Override
public void onBackPressed() {

    int count = getSupportFragmentManager().getBackStackEntryCount();

    if (count == 0) {
        super.onBackPressed();
        //additional code
    } else {
        getSupportFragmentManager().popBackStack();
    }

}

片段: 创建一个BaseFragment,放置一个方法:

 public boolean onBackPressed();

活动:

@Override
public void onBackPressed() {
    List<Fragment> fragments = getSupportFragmentManager().getFragments();
    if (fragments != null) {
        for (Fragment fragment : fragments) {
            if (!fragment.isVisible()) continue;

            if (fragment instanceof BaseFragment && ((BaseFragment) fragment).onBackPressed()) {
                return;
            }
        }
    }

    super.onBackPressed();
}

你的活动将在附加的和可见的片段上运行,并对它们中的每一个调用onBackPressed(),如果其中一个返回'true'(意味着它已经被处理,所以没有进一步的操作),则中止。

我使用的另一种方法如下:

一个Otto事件总线,用于在活动及其片段之间进行通信 Activity中的堆栈,包含在调用片段定义的Runnable中包装的自定义后退操作 当onBackPressed在控制Activity中被调用时,它弹出最近的自定义后退动作并执行它的Runnable。如果Stack上没有任何东西,则会调用默认的super.onBackPressed()

这里包含了完整的方法和示例代码,作为对另一个SO问题的回答。

我只是使用findFragmentById和转换到片段,并调用处理onBackpressed的方法。这个示例显示了检查这是否是订单流程的第一步,如果弹出一个对话框片段来确认退出订单。

@Override
    public void onBackPressed() {
        //check if first fragment in wizard is loaded, if true get abandon confirmation before going back
        OrderFragment frag =(OrderFragment)getSupportFragmentManager().findFragmentById(R.id.fragContainer);
        if (frag==null || (frag!=null && frag.getOrderStage()<1)){
            AlertDialogFragment.show(getSupportFragmentManager(), R.string.dialog_cancel_order,R.string.dialog_cancel_order_msg, R.string.dialog_cancel_order_pos,R.string.dialog_order_quiz_neg, DIALOG_ID_CANCEL);
        }else {
            super.onBackPressed();
        }
    }