我最近更新了我的依赖项,以将OnBackPressedCallback
的更改从接口更改为抽象类。
我已经根据新文档here进行了设置,但是我觉得事情没有按预期进行。
我的片段的OnCreate
与文档非常相似:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
requireActivity().onBackPressedDispatcher.addCallback(this) {
backPressed()
}
}
当我按下“后退”按钮时,backPressed()
中的代码将运行,但是什么也没有发生。
我尝试从回调内部调用handleBackPressed()
,requireActivity().onBackPressedDispatcher.onBackPressed()
和requireActivity().onBackPressed()
,但是所有这些都会导致StackOverflowError,因为它似乎是递归地运行该回调。
肯定有一些我很想念的东西...
答案 0 :(得分:6)
肯定有一些我很想念的东西...
您忘了在片段中禁用自定义回调,然后再要求Activity处理后退键。
适合我的解决方案:
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final OnBackPressedCallback callback = new OnBackPressedCallback(true) {
@Override
public void handleOnBackPressed() {
if (/*situation to handle back pressing*/){
//here handle your backPress in your fragment
} else {
setEnabled(false); //this is important line
requireActivity().onBackPressed();
}
}
};
requireActivity().getOnBackPressedDispatcher().addCallback(this, callback);
}
答案 1 :(得分:1)
注册OnBackPressedCallback
时,您将负责处理后退按钮。这意味着当您收到回调时,不会再发生其他任何后按行为。
如果您使用的是Navigation,则可以使用NavController
弹出后堆栈:
requireActivity().onBackPressedDispatcher.addCallback(this) {
backPressed()
// Now actually go back
findNavController().popBackStack()
}
答案 2 :(得分:0)
这在androidx.appcompat:appcompat:1.1.0
中对我有用
requireActivity().onBackPressedDispatcher.addCallback(
this,
object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
Log.d(TAG, "Fragment back pressed invoked")
// Do custom work here
// if you want onBackPressed() to be called as normal afterwards
if (isEnabled) {
isEnabled = false
requireActivity().onBackPressed()
}
}
}
)
答案 3 :(得分:0)
如果不再需要回调,也可以删除回调而不是将其设置为启用。我将其与这样的嵌套图一起使用,因为当您使用NavHostFragment触摸嵌套导航图时,它会将其从主片段回栈中移除,而不是在嵌套导航图中打开最后一个片段。
// Get NavHostFragment
val navHostFragment =
childFragmentManager.findFragmentById(R.id.nested_nav_host_fragment)
// ChildFragmentManager of the current NavHostFragment
val navHostChildFragmentManager = navHostFragment?.childFragmentManager
val callback = object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
val backStackEntryCount = navHostChildFragmentManager!!.backStackEntryCount
if (backStackEntryCount == 1) {
// We are at the root of nested navigation, remove this callback
remove()
requireActivity().onBackPressed()
} else {
navController?.navigateUp()
}
}
}
requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner, callback)