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

Android Activity切换动画异常:API34下overrideActivityTransition未达预期

Activity切换动画适配问题及解决方案

需求与初始实现

要实现Activity切换动画:从Activity A启动Activity B时,A向左滑出屏幕,B从右侧滑入。初始采用版本兼容逻辑:

if (Build.VERSION.SDK_INT >= 34) {
    overrideActivityTransition(
            ComponentActivity.OVERRIDE_TRANSITION_OPEN,
            R.anim.slide_in_from_right,
            R.anim.slide_out_left
        )
    } else overridePendingTransition(
        R.anim.slide_in_from_right,
        R.anim.slide_out_left
    )

具体代码实现

T1Activity(启动页)

class T1Activity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            AndroidMex4Theme {
                T1Screen() { startNextActivity() }
            }
        }
    }

    private fun startNextActivity() {
        startActivity(Intent(this@T1Activity, T2Activity::class.java))
        if (Build.VERSION.SDK_INT < 34) overridePendingTransition(
            R.anim.slide_in_from_right,
            R.anim.slide_out_left,
        ) else overrideActivityTransition(
            OVERRIDE_TRANSITION_OPEN,
            R.anim.slide_in_from_right,
            R.anim.slide_out_left,
        )
    }
}

T2Activity(目标页)

class T2Activity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        if (Build.VERSION.SDK_INT >= 34) {
            overrideActivityTransition(
                OVERRIDE_TRANSITION_OPEN,
                R.anim.slide_in_from_right,
                R.anim.slide_out_left,
            )
        }

        super.onCreate(savedInstanceState)

        setContent {
            AndroidMex4Theme {
                T2Screen { startNextActivity() }
            }
        }
    }
}

动画文件定义

slide_in_from_right

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="300">

    <translate
        android:fromXDelta="100%"
        android:toXDelta="0%"
 />
 </set>

slide_out_left

<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="300">
    <translate
        android:fromXDelta="0"
        android:toXDelta="-100%"
    />
</set>

遇到的问题

  • SDK<34时,overridePendingTransition勉强生效,但Activity A会闪烁变白后消失
  • SDK34时,overrideActivityTransition效果不稳定,仅成功一次无法复现,且Activity B实际从左侧滑入而非右侧
  • 需要添加FLAG_ACTIVITY_NEW_TASK和FLAG_ACTIVITY_CLEAR_TASK清除返回栈,增加实现复杂度
  • 不理解overrideActivityTransition中OVERRIDE_TRANSITION_OPEN/CLOSE的作用,不清楚如何实现返回时的反向动画

解决方案

1. 修复SDK<34时的闪白问题

闪白源于Activity启动时的默认背景,给目标Activity添加透明主题:
在styles.xml中定义:

<style name="TransparentActivityTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="android:windowBackground">@android:color/transparent</item>
    <item name="android:windowIsTranslucent">true</item>
</style>

在Manifest中为Activity绑定该主题:

<activity android:name=".T1Activity" android:theme="@style/TransparentActivityTheme"/>
<activity android:name=".T2Activity" android:theme="@style/TransparentActivityTheme"/>

2. 正确使用SDK34+的overrideActivityTransition

  • OVERRIDE_TRANSITION_OPEN:用于启动新Activity时的进入/退出动画
  • OVERRIDE_TRANSITION_CLOSE:用于当前Activity被finish(如返回操作)时的进入/退出动画
  • 注意:该方法需在startActivity或finish之前调用,而非之后

修改T1Activity的启动逻辑:

private fun startNextActivity() {
    if (Build.VERSION.SDK_INT >= 34) {
        overrideActivityTransition(
            OVERRIDE_TRANSITION_OPEN,
            R.anim.slide_in_from_right,
            R.anim.slide_out_left
        )
    }
    startActivity(Intent(this@T1Activity, T2Activity::class.java))
    if (Build.VERSION.SDK_INT < 34) {
        overridePendingTransition(
            R.anim.slide_in_from_right,
            R.anim.slide_out_left
        )
    }
}

3. 处理返回栈清除时的动画

使用FLAG_ACTIVITY_NEW_TASK和FLAG_ACTIVITY_CLEAR_TASK时,需在启动前设置过渡:

private fun startNextActivityWithClearStack() {
    val intent = Intent(this@T1Activity, T2Activity::class.java).apply {
        flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
    }
    if (Build.VERSION.SDK_INT >= 34) {
        overrideActivityTransition(
            OVERRIDE_TRANSITION_OPEN,
            R.anim.slide_in_from_right,
            R.anim.slide_out_left
        )
    }
    startActivity(intent)
    if (Build.VERSION.SDK_INT < 34) {
        overridePendingTransition(
            R.anim.slide_in_from_right,
            R.anim.slide_out_left
        )
    }
}

4. 实现返回时的反向动画

首先定义反向动画文件:

slide_in_from_left.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="300">
    <translate
        android:fromXDelta="-100%"
        android:toXDelta="0%"
    />
</set>

slide_out_right.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="300">
    <translate
        android:fromXDelta="0%"
        android:toXDelta="100%"
    />
</set>

然后在Activity中处理返回逻辑:

override fun onBackPressed() {
    if (Build.VERSION.SDK_INT >= 34) {
        overrideActivityTransition(
            OVERRIDE_TRANSITION_CLOSE,
            R.anim.slide_in_from_left,
            R.anim.slide_out_right
        )
    }
    super.onBackPressed()
    if (Build.VERSION.SDK_INT < 34) {
        overridePendingTransition(
            R.anim.slide_in_from_left,
            R.anim.slide_out_right
        )
    }
}

或使用Jetpack的OnBackPressedDispatcher:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    // ...其他初始化代码
    onBackPressedDispatcher.addCallback(this) {
        if (Build.VERSION.SDK_INT >= 34) {
            overrideActivityTransition(
                OVERRIDE_TRANSITION_CLOSE,
                R.anim.slide_in_from_left,
                R.anim.slide_out_right
            )
        }
        finish()
        if (Build.VERSION.SDK_INT < 34) {
            overridePendingTransition(
                R.anim.slide_in_from_left,
                R.anim.slide_out_right
            )
        }
    }
}

内容的提问来源于stack exchange,提问作者shadox

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 17:43:23