You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 21:13:18