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
就会启用。我不确定是否有快速解决方法。
我希望 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
就会启用。我不确定是否有快速解决方法。