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

FragmentContainerView结合popUpTo的弹出动画层级异常问题

问题描述

布局与导航配置

主Activity使用FragmentContainerView承载导航组件:

<androidx.fragment.app.FragmentContainerView
    android:id="@+id/nav_host_fragment"
    android:name="androidx.navigation.fragment.NavHostFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:defaultNavHost="true"
    app:navGraph="@navigation/main_nav_graph" />

现有三个Fragment(A、B、C),A→B、B→C均配置右侧滑入动画:

<action
    android:id="@+id/a_to_b"
    app:destination="@id/b"
    app:enterAnim="@anim/slide_in_right"
    app:exitAnim="@anim/nothing"
    app:popEnterAnim="@anim/nothing"
    app:popExitAnim="@anim/slide_out_right" />

Fragment C的「X」按钮点击后,配置直接返回Fragment A并伴随向下滑出动画:

<action
    android:id="@+id/cancel"
    app:destination="@id/a"
    app:enterAnim="@anim/nothing"
    app:exitAnim="@anim/slide_out_bottom"
    app:popEnterAnim="@anim/nothing"
    app:popExitAnim="@anim/nothing"
    app:popUpTo="@id/a"
    app:popUpToInclusive="true" />

动画文件

  • Nothing动画(res/anim/nothing.xml):
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="300"
    android:fromYDelta="0%p"
    android:toYDelta="0%p" />
  • 右侧滑入动画(res/anim/slide_in_right.xml):
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="300"
    android:fromXDelta="100%p"
    android:toXDelta="0" />
  • 向下滑出动画(res/anim/slide_out_bottom.xml):
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromYDelta="0%p" android:toYDelta="100%p"
    android:duration="300"/>

异常现象

除取消操作外,其余导航均正常。但点击C的「X」按钮时,Fragment A会直接覆盖在C之上,导致看不到C的向下滑出动画。预期弹出操作时,退出的Fragment(C)应绘制在进入的Fragment(A)之上,才能展示退出动画。


解决方案

核心原因

使用popUpTo并设置inclusive="true"时,导航组件会先将目标Fragment(A)加载到视图层级,再执行退出Fragment(C)的动画,导致A覆盖C。要让C的退出动画可见,需调整视图层级顺序,让C在动画期间保持在A上方。

具体实现

  1. 修改导航Action配置(推荐)
    移除app:popUpToInclusive="true",调整后的Action配置:
<action
    android:id="@+id/cancel"
    app:destination="@id/a"
    app:enterAnim="@anim/nothing"
    app:exitAnim="@anim/slide_out_bottom"
    app:popEnterAnim="@anim/nothing"
    app:popExitAnim="@anim/nothing"
    app:popUpTo="@id/a" />

此配置会弹出B和C回到A,此时C作为退出的Fragment会在A上方执行动画,符合预期效果。

  1. 调整动画的Z轴层级
    在slide_out_bottom.xml中添加android:zAdjustment="top",强制动画执行期间将视图置于顶层:
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromYDelta="0%p" android:toYDelta="100%p"
    android:duration="300"
    android:zAdjustment="top"/>

该属性会让执行动画的视图在动画期间临时提升Z轴层级,确保不会被新Fragment覆盖。

  1. 手动控制视图层级(备选)
    在Fragment C的按钮点击事件中,先将C的视图置顶再执行导航:
// Fragment C中按钮点击逻辑
view?.bringToFront()
findNavController().navigate(R.id.cancel)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 16:50:16