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

时间:2019-06-09 16:06:51

标签: android androidx android-jetpack android-architecture-navigation

我最近更新了我的依赖项,以将OnBackPressedCallback的更改从接口更改为抽象类。

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

我的片段的OnCreate与文档非常相似:

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

当我按下“后退”按钮时,backPressed()中的代码将运行,但是什么也没有发生。

我尝试从回调内部调用handleBackPressed()requireActivity().onBackPressedDispatcher.onBackPressed()requireActivity().onBackPressed(),但是所有这些都会导致StackOverflowError,因为它似乎是递归地运行该回调。

肯定有一些我很想念的东西...

4 个答案:

答案 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)