https://developer.android.com/guide/navigation/custom-back/predictive-back-gesture
enableOnBackInvokedCallback 功能解析
android:enableOnBackInvokedCallback="true" 是 Android 13 (API 33) 引入的一个属性,用于启用**预测性返回手势(Predictive Back Gesture)**功能。
核心作用
启用新的返回导航回调系统,让系统能够预测 用户按下返回键后会发生什么,并提供动画预览。
具体表现
启用前(传统行为)
- 用户按返回键 → 立即执行返回操作
- 无法预览返回后的界面
启用后(预测性返回)
- 用户滑动返回手势时,可以看到即将返回到的界面预览
- 用户可以在手势过程中取消返回操作
- 提供流畅的过渡动画
视觉效果示例
┌──────────────┐ 滑动中预览 ┌──────────────┐
│ 当前页面 │ ←───────────────→ │ 上一页面 │
│ │ (可取消返回) │ (模糊预览) │
└──────────────┘ └──────────────┘
代码适配要求
启用此功能后,需要将旧的 onBackPressed() 迁移到新的回调 API:
kotlin
// ❌ 旧方式(将被废弃)
override fun onBackPressed() {
// 处理返回逻辑
}
// ✅ 新方式
val callback = object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
// 处理返回逻辑
}
}
onBackPressedDispatcher.addCallback(this, callback)
注意事项
| 项目 | 说明 |
|---|---|
| 最低 API | Android 13 (API 33) |
| 默认值 | false(为了向后兼容) |
| 要求 | 需要适配新的 OnBackInvokedCallback API |
| 不兼容代码 | 直接拦截 KeyEvent.KEYCODE_BACK 或重写 onBackPressed() |
是否应该启用?
- ✅ 新项目:建议启用,提供更好的用户体验
- ⚠️ 旧项目:需要先检查并迁移所有返回逻辑,否则可能导致返回行为异常
官方文档
Google 计划在未来的 Android 版本中将此功能设为默认行为,因此建议尽早适配。
针对特定 Activity 配置 enableOnBackInvokedCallback
这个属性支持在 <activity> 级别单独配置。
配置方式
xml
<application
android:enableOnBackInvokedCallback="false"
... >
<!-- 默认关闭,这些 Activity 不受影响 -->
<activity android:name=".MainActivity" />
<activity android:name=".SettingsActivity" />
<!-- 特定 Activity 单独启用 -->
<activity
android:name=".NewFeatureActivity"
android:enableOnBackInvokedCallback="true" />
<activity
android:name=".ModernActivity"
android:enableOnBackInvokedCallback="true" />
</application>
配置逻辑
| Application 设置 | Activity 设置 | 最终效果 |
|---|---|---|
false |
未设置 | 关闭 |
false |
true |
开启 ✅ |
true |
未设置 | 开启 |
true |
false |
关闭 |
注意事项
-
compileSdk 要求 :需要
compileSdk至少为 34 (API 34) 才能在 Activity 级别使用此属性 -
默认值 :
enableOnBackInvokedCallback的默认值是true,所以如果你想大部分 Activity 关闭,需要在<application>级别显式设置为false -
渐进式迁移:这种方式非常适合渐进式迁移------先在 Application 级别关闭,然后逐个 Activity 适配并开启
使用场景
xml
<!-- 推荐:渐进式迁移策略 -->
<application
android:enableOnBackInvokedCallback="false">
<!-- 已完成适配的 Activity -->
<activity
android:name=".feature.NewCheckoutActivity"
android:enableOnBackInvokedCallback="true" />
<!-- 未适配的 Activity 保持旧行为,无需修改 -->
<activity android:name=".legacy.OldActivity" />
</application>
这样你可以安全地逐步迁移,而不用担心未适配的 Activity 出现问题。