Android Java使用Navigation时Fragment确认弹窗点Yes返回上一页方法
Fragment拦截返回键后确认返回的实现方案
你当前通过OnBackPressedCallback拦截返回事件后,默认返回逻辑已经被回调接管,点击弹窗「Yes」按钮时不要直接手动操作Fragment栈,按照系统返回事件的分发逻辑处理即可,具体实现如下:
核心实现逻辑
- 由于拦截回调处于启用状态时会消费所有返回事件,确认返回时首先要关闭当前回调的拦截状态
- 重新触发Activity的返回事件分发,此时系统会自动执行默认返回逻辑,回到上一个Fragment,不会破坏返回事件链上的其他拦截逻辑
修改后的完整代码
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); final OnBackPressedCallback callback = new OnBackPressedCallback(true) { @Override public void handleOnBackPressed() { AlertDialog.Builder builder= new AlertDialog.Builder(requireContext()); builder.setMessage("Are you sure you want to logout"); builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { // 禁用当前回调,不再拦截后续返回事件 setEnabled(false); // 重新触发返回,自动执行默认返回栈弹出逻辑 requireActivity().onBackPressed(); } }); builder.setNegativeButton("No", null); builder.show(); } }; requireActivity().getOnBackPressedDispatcher().addCallback(this, callback); }
注意事项
- 不推荐直接调用
getParentFragmentManager().popBackStack()实现返回:这种写法会绕过OnBackPressedDispatcher的事件分发链,如果当前页面还有其他注册的返回拦截逻辑(比如全局弹窗拦截、Navigation组件的返回拦截),会被直接跳过引发状态异常。 - 如果你使用Jetpack Navigation组件做导航管理,上述写法同样兼容,不需要额外调用
NavController.popBackStack(),返回逻辑会自动对接导航组件的栈管理。 - 注册回调时传入了当前Fragment作为生命周期持有者,Fragment销毁时回调会自动被移除,不需要手动做解绑处理,不会引发内存泄漏。
内容的提问来源于stack exchange,提问作者Ibanez1408
相关产品推荐
相关产品推荐

