我计划实现这样的导航:
![enter image description here](https://istack.dev59.com/RL7Iz.webp)
我面临的问题是当用户在
我使用条件导航来导航到
如何正确实现呢?
![enter image description here](https://istack.dev59.com/RL7Iz.webp)
我面临的问题是当用户在
LoginFragment
页面按返回按钮时,它会再次加载 LoginFragment
,即陷入循环中。我使用条件导航来导航到
LoginFragment
,具体实现请参考此答案。如何正确实现呢?
LoginFragment
页面按返回按钮时,它会再次加载 LoginFragment
,即陷入循环中。LoginFragment
,具体实现请参考此答案。我认为在我的应用程序中如何执行它会更加简洁。只需在导航图中添加以下设置:
<fragment
android:id="@+id/profile_dest"
android:name="com.example.ProfileFragment">
<action
android:id="@+id/action_profile_dest_to_login_dest"
app:destination="@id/login_dest"
app:popUpTo="@+id/profile_dest"
app:popUpToInclusive="true" />
</fragment>
然后通过 findNavController().navigate(R.id.action_profile_dest_to_login_dest)
导航到登录页面。
popUpTo
和 popUpToInclusive
在导航到 LoginFragment
页面时关闭了 ProfileFragment
页面,所以如果用户返回,应用程序将退出。
popUpTo="@+id/login_dest"
和 popUpToInclusive="true"
。不要使用 popBackStack()
。 - Carson Holzheimer我可以提出的一种解决方案是,在您的活动中覆盖onBackPressed方法,并在当前目标(在处理后退之前)为登录片段时完成该活动。
override fun onBackPressed() {
val currentDestination=NavHostFragment.findNavController(nav_host_fragment).currentDestination
when(currentDestination.id) {
R.id.loginFragment -> {
finish()
}
}
super.onBackPressed()
}
exit(0)
还是 finish()
?这两者之间有什么区别? - Yaswant NarayanLOGIN_SUCCESSFUL
状态,可能是个人资料片段或任何需要登录的其他片段。class LoginFragment : Fragment(R.layout.login) {
...
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
val navController = findNavController()
val savedStateHandle = navController.previousBackStackEntry?.savedStateHandle
?: throw IllegalStateException("the login fragment must not be a start destination")
savedStateHandle.set(LOGIN_SUCCESSFUL, false)
// Hook up your UI, ask for login
userRepository.addLoginSuccessListener {
savedStateHandle.set(LOGIN_SUCCESSFUL, true)
navController.popBackStack()
}
}
}
LOGIN_SUCCESSFUL
状态并对其进行处理。请注意,观察者lambda表达式只有在登录片段放置结果并返回到个人资料片段后才会被调用。class ProfileFragment : Fragment(R.layout.profile) {
...
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
val navController = findNavController()
viewLifecycleOwner.lifecycleScope.launchWhenStarted {
userRepository.userFlow.collect { user ->
if (user == null) {
navController.navigate(R.id.login)
}
}
}
val savedStateHandle = navController.currentBackStackEntry?.savedStateHandle
?: throw IllegalStateException()
savedStateHandle.getLiveData<Boolean>(LOGIN_SUCCESSFUL)
.observe(viewLifecycleOwner) { success ->
if (!success) {
// do whathever we want, just for an example go to
// the start destination which doesn't require login
val startDestination = navController.graph.startDestination
navController.navigate(startDestination, navOptions {
popUpTo(startDestination {
inclusive = true
})
})
}
}
}
}