引言
1. Activity 级别的回退处理
方法一:重写 onBackPressed()
Kotlin
@Override
public void onBackPressed() {
if (shouldCustomHandleBack) {
// 自定义回退逻辑
handleCustomBackAction();
} else {
// 默认行为
super.onBackPressed();
}
}
方法二:使用 onBackPressedDispatcher(推荐)
Kotlin
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
if (shouldInterceptBackPress) {
// 拦截回退事件
showExitConfirmation()
} else {
// 允许默认行为
isEnabled = false
onBackPressed()
}
}
})
}
}
用的时候发现,官方已经onBackPressed 废弃了。
现在推荐这样处理"返回":在 Activity 里 用 OnBackPressedDispatcher + OnBackPressedCallback。
正文
在 Activity 里
用 OnBackPressedDispatcher + OnBackPressedCallback。
Kotlin
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
onBackPressedDispatcher.addCallback(this,
object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
// TODO: 自定义返回逻辑
// e.g. 先关闭抽屉/弹窗,否则再退出
finish()
}
}
)
}
}
如果你只是想"触发默认返回",调用:
onBackPressedDispatcher.onBackPressed()
在 Fragment 里
用 viewLifecycleOwner
绑定生命周期(避免内存泄露):
Kotlin
class DemoFragment : Fragment(R.layout.fragment_demo) {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
requireActivity().onBackPressedDispatcher.addCallback(
viewLifecycleOwner,
object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
// TODO: Fragment 内自定义返回
// 例如先消费一次返回,不想消费时可以:
// isEnabled = false
// requireActivity().onBackPressedDispatcher.onBackPressed()
}
}
)
}
}
Jetpack Navigation
如果用了 NavController
,一般无需手动拦截:
// Toolbar 左上角返回键
toolbar.setNavigationOnClickListener { navController.navigateUp() }
想自定义时,再用上面的 OnBackPressedCallback
协调。
Jetpack Compose
用 androidx.activity.compose.BackHandler
:
Kotlin
BackHandler(enabled = true) {
// 自定义返回
}
小结
-
不要再重写
onBackPressed()
。 -
首选 OnBackPressedDispatcher + OnBackPressedCallback(Activity/Fragment/Compose 都有对应做法)。
-
用 Navigation 时,默认就支持返回;需要拦截再加 Callback。
-
Android 13+ 若要玩预测性返回的高级用法,再考虑
OnBackInvokedCallback
。