Fragment中返回键拦截失效,如何阻止返回至上一Fragment?
问题代码
@Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { setHasOptionsMenu(true); requireActivity().getOnBackPressedDispatcher().addCallback(getViewLifecycleOwner(), new OnBackPressedCallback(true) { @Override public void handleOnBackPressed() { this.setEnabled(false); } }); return mBinding.getRoot(); } @Override public boolean onOptionsItemSelected(@NonNull MenuItem item) { //noinspection SwitchStatementWithTooFewBranches switch (item.getItemId()) { case android.R.id.home: callParentMethod(); return true; } return false; } private void callParentMethod() { requireActivity().onBackPressed(); }
问题原因
你的拦截逻辑存在两处漏洞:
- 返回键回调中调用
this.setEnabled(false)会直接禁用当前回调,后续点击返回键时系统会跳过这个拦截逻辑,执行默认的返回流程(回到上一Fragment)。 - 点击左上角Home返回箭头时,
callParentMethod()直接调用了Activity的onBackPressed(),等同于触发默认返回操作,自然会回到上一Fragment。
修改方案
要彻底阻止返回至上一Fragment,需做两处调整:
1. 修复返回键拦截逻辑
去掉setEnabled(false),保持回调处于启用状态,直接拦截返回操作:
requireActivity().getOnBackPressedDispatcher().addCallback(getViewLifecycleOwner(), new OnBackPressedCallback(true) { @Override public void handleOnBackPressed() { // 此处可添加自定义逻辑(比如弹窗提示),或直接空实现拦截返回 // 不要调用setEnabled(false),确保回调始终生效 } });
2. 修复Home键点击逻辑
不再触发Activity的返回流程,直接拦截:
@Override public boolean onOptionsItemSelected(@NonNull MenuItem item) { switch (item.getItemId()) { case android.R.id.home: // 直接拦截,或添加自定义处理逻辑 return true; } return super.onOptionsItemSelected(item); }
如果需要在特定条件下允许返回,可在回调中增加判断:
@Override public void handleOnBackPressed() { if (满足返回条件) { this.setEnabled(false); requireActivity().onBackPressed(); } else { // 拦截返回,执行自定义逻辑 } }
内容的提问来源于stack exchange,提问作者Shahriar
相关产品推荐
相关产品推荐

