正在调用 OnBackPressedCallback,但应用程序不会返回

OnBackPressedCallback is being called, but app is not going back

我最近更新了我的依赖项以包括 OnBackPressedCallback 从接口到抽象的更改 class。

我已经根据新文档进行了设置 here,但我觉得事情没有按预期进行。

我的片段 OnCreate 看起来很像文档:

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        requireActivity().onBackPressedDispatcher.addCallback(this) {
            backPressed()
    }
}

当我按下后退按钮时,backPressed() 中的代码是 运行,但没有任何反应。

我试过从回调内部调用 handleBackPressed()requireActivity().onBackPressedDispatcher.onBackPressed() 以及 requireActivity().onBackPressed(),但这些都会导致 WhosebugError,因为它似乎 运行 该回调是递归的。

一定有一些非常明显的东西我错过了......

当您注册 OnBackPressedCallback 时,您将负责处理后退按钮。这意味着当您收到回调时,不会发生其他按下行为。

如果您正在使用 Navigation,您可以使用 NavController 弹出返回堆栈:

requireActivity().onBackPressedDispatcher.addCallback(this) {
    backPressed()
    // Now actually go back
    findNavController().popBackStack()
}

这在 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()
                }
            }
        }
    )

There has got to be something really obvious I am missing...

在请求 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);
    }

如果不再需要回调,您也可以移除回调而不是设置启用。我将它与这样的嵌套图一起使用,因为当您使用它的 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)