Androidx OnBackPressedDispatcher - 如何使用后退按钮按下

Androidx OnBackPressedDispatcher - how to consume the back button press

我希望 onBackPressedDispatcher 有时吸收后退按钮的按下,但我没有看到它的选项。发生的事情是,我们今天才尝试升级到 androidX 中的 onBackPressedDispatcher,但我们已经覆盖了 activity 中的 onBackPress。因此,当我们的 onBackPressedDispatcher 之后调用 OnBackPressedCallback 时,也会调用活动 onBackPressed 覆盖。我们不想要那个。 onBackpressed 应该当场消费。这是我目前所拥有的:

    const val TAG = "MyTag"

class MyActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_first)
        MyTester(this)
    }

    override fun onBackPressed() {
        super.onBackPressed()
        Log.v(TAG, "Activities class back button Pressed")

    }

    inner class MyTester(var activity: AppCompatActivity) {
        init {
            addBackCB()
        }

        fun addBackCB() {
            var callback = object : OnBackPressedCallback(true) {
                override fun handleOnBackPressed() {
                    Log.v(TAG, "inner class MyTester back button")
                }
            }
            activity.onBackPressedDispatcher.addCallback(activity, callback);
        }
    }
}

打印以下内容:

V/MyTag: inner class MyTester back button
V/MyTag: Activities class back button Pressed

如果我不调用 super.onBackPressed(),那么调度程序甚至无法工作。它需要那个电话。

这是因为在ComponentActivity.onBackPressed()中调用了OnBackPressedDispatcher,如果看源码:

    @Override
    @MainThread
    public void onBackPressed() {
        mOnBackPressedDispatcher.onBackPressed();
    }

因此,如果您覆盖 onBackPressed 并且从不调用 super 方法,您将永远无法到达回调。我认为 OnBackPressedDispatcher 背后的整个想法是,如果您希望片段拦截回按,则不必覆盖 Activity.onBackPressed。这个提到了in one of the guides.

如果你真的想让你的 activity 处理后压,你可以在你的覆盖中尝试这样的事情:

    if (onBackPressedDispatcher.hasEnabledCallbacks()) {
      // There's an active callback; let the fragment handle it
      super.onBackPressed()
    } else {
      // Do your activity's back press handling here
    }

不过要小心。亲自尝试后,您可能会发现 hasEnabledCallbacks 会 return 为真,即使您自己没有添加任何回调。这是因为您的 FragmentManager 有自己的后按回调,只要 backStackEntryCount > 0 就会启用。我不确定是否有快速解决方法。