Androidx OnBackPressedDispatcher - 如何消费后退按钮按下事件

7
我希望能够将onBackPressedDispatcher吸收后退按钮的按下事件。但有时我并没有看到这个选项。情况是我们今天正在尝试升级到androidX中的onBackPressedDispatcher,但我们已经在activity中覆盖了onBackPressd。所以当我们的onBackPressedDispatcher之后调用OnBackPressedCallback时,还会调用activities的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(),则分发器甚至无法工作。它需要那个调用。
1个回答

29
这是因为在ComponentActivity.onBackPressed()中调用了OnBackPressedDispatcher,如果您查看源代码:
    @Override
    @MainThread
    public void onBackPressed() {
        mOnBackPressedDispatcher.onBackPressed();
    }

如果你覆盖了onBackPressed并且没有调用super方法,那么你将永远无法达到回调函数。我认为OnBackPressedDispatcher背后的整个理念是,如果你想让你的fragment拦截返回事件,就不应该覆盖Activity.onBackPressed。这在指南中有提到。

如果你真的希望你的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也会返回true。这是因为你的FragmentManager有它自己的后退按键回调函数,当backStackEntryCount > 0时它将被激活。我不确定是否有快速解决办法。


嗨,是的,这个可以工作,但我有一个小问题。当我从嵌套片段返回时,它可以正常工作,但现在我在第一个活动上,按下返回键会打开空白屏幕。 - Sunil Chaudhary
@SunilChaudhary,我不太擅长Kotlin,但我猜你可以使用Intent来重定向到所需的页面,这至少是我在我的项目中所做的。 - Abdulrahman Hasanato

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接