API 34以下设备返回手势导航与返回Activity转场不一致问题
Android低版本返回转场一致性解决方案
问题背景
官方文档仅针对Android 14+(API 34+)提供返回转场实现指导,未覆盖低版本处理逻辑。尝试的初始实现存在兼容性问题:
初始代码:
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { overrideActivityTransition(AppCompatActivity.OVERRIDE_TRANSITION_OPEN, R.anim.slide_in_from_bottom, 0) overrideActivityTransition(AppCompatActivity.OVERRIDE_TRANSITION_CLOSE, R.anim.stay, R.anim.slide_out_to_bottom) } else { @Suppress("DEPRECATION") overridePendingTransition(R.anim.slide_in_from_bottom, R.anim.stay) } //... @Suppress("DEPRECATION") @Deprecated("") override fun onBackPressed() { super.onBackPressed() if (Build.VERSION.SDK_INT < Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { @Suppress("DEPRECATION") overridePendingTransition(R.anim.stay, R.anim.slide_out_to_bottom) } } //... fun handleUiStuff() { onCloseButtonClick = { onBackPressedDispatcher.onBackPressed() } }
问题现象
- API 34+设备:转场表现正常,打开、关闭及返回手势转场一致。
- API 33及以下设备:打开转场正常;硬件返回键触发的关闭转场正常,但通过UI组件调用
onBackPressedDispatcher.onBackPressed()时,重写的旧版onBackPressed()方法不会被触发,导致overridePendingTransition未执行,自定义转场失效。
需求:保证转场一致性,避免在复杂场景(如使用BackHandler)中重复编写转场代码。
解决方案
通过OnBackPressedCallback统一处理返回逻辑,替代旧版onBackPressed()重写,确保所有返回触发路径都能执行转场动画:
修改后的代码:
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // 初始化打开转场 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { overrideActivityTransition(AppCompatActivity.OVERRIDE_TRANSITION_OPEN, R.anim.slide_in_from_bottom, 0) overrideActivityTransition(AppCompatActivity.OVERRIDE_TRANSITION_CLOSE, R.anim.stay, R.anim.slide_out_to_bottom) } else { @Suppress("DEPRECATION") overridePendingTransition(R.anim.slide_in_from_bottom, R.anim.stay) } // 统一拦截返回事件,兼容低版本 onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) { override fun handleOnBackPressed() { // 执行页面关闭操作 finish() // 低版本执行关闭转场 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { @Suppress("DEPRECATION") overridePendingTransition(R.anim.stay, R.anim.slide_out_to_bottom) } // 移除回调避免重复触发 remove() } }) //... } // 移除原有的onBackPressed()重写方法 fun handleUiStuff() { onCloseButtonClick = { onBackPressedDispatcher.onBackPressed() } }
方案说明
OnBackPressedCallback会拦截所有返回事件(包括硬件返回键、onBackPressedDispatcher调用),确保低版本下转场逻辑统一执行。- 构造参数
true表示默认启用该回调,需手动调用finish()完成页面关闭。 - 执行完转场后调用
remove(),避免后续返回事件重复触发该回调(若需保留回调处理其他逻辑,可调整此逻辑)。
内容的提问来源于stack exchange,提问作者Carsten Hagemann
相关产品推荐
相关产品推荐

