Kotlin中Fragment跳转后清除Back Stack(避免返回Splash Screen)
我明白你的困扰——用Splash Fragment跳转后,返回键居然还能回到启动页,这确实不符合用户预期。其实不用调用activity?.finish()(这会直接关掉整个应用,当然不行),用Navigation Component自带的回退栈控制就能轻松解决,而且完全在Fragment里处理,不用碰Activity的代码。
给你两种可行的方案,选哪种都可以:
方案1:在导航图(navigation.xml)里配置Action属性
这是最直观的方式,直接在跳转的Action里设置清除回退栈的规则:
打开你的导航图文件,找到action_splashScreen_to_dashboard这个Action,添加app:popUpTo和app:popUpToInclusive="true"属性:
<action android:id="@+id/action_splashScreen_to_dashboard" app:destination="@id/dashboard" app:popUpTo="@id/splashScreen" app:popUpToInclusive="true"/>
app:popUpTo="@id/splashScreen":表示跳转后要回退到Splash Fragment这个节点app:popUpToInclusive="true":表示把Splash Fragment本身也从回退栈里移除
这样配置后,你原来的Fragment代码完全不用改,跳转后回退栈里就只剩下Dashboard Fragment了,按返回键会直接退出应用,不会回到Splash。
方案2:在代码中使用NavOptions动态配置
如果不想修改导航图,也可以在跳转时通过代码构建NavOptions来实现:
修改Splash Fragment里的跳转代码:
Handler().postDelayed({ val navOptions = NavOptions.Builder() .setPopUpTo(R.id.splashScreen, true) // 第二个参数为true,移除Splash本身 .build() findNavController().navigate(R.id.action_splashScreen_to_dashboard, null, navOptions) }, 3000)
这个逻辑和方案1完全一致,只是把配置从xml移到了代码里,适合需要动态判断是否清除回退栈的场景。
为什么之前的activity?.finish()不行?
因为你的架构是单Activity多Fragment,调用activity?.finish()会直接销毁唯一的Activity,整个应用自然就关闭了——这和你想要的“清除Fragment回退栈”完全不是一回事。
现在试试上面的方案,跳转后按返回键应该就不会回到Splash了,完美符合你说的“支付成功后返回不回到支付页”的场景~
内容的提问来源于stack exchange,提问作者Irfan Ahamed S

