导航架构组件 - 登录屏幕 [英] Navigation Architecture Component - Login screen
问题描述
我打算实现这样的导航:
我面临的问题是当用户在 LoginFragmennt
并按下后退按钮时它再次加载 LognFragment
即.陷入循环.
I am planning to implement navigation like this:
The problem I face is when user is in LoginFragmennt
and presses back button it again loads up LognFragment
ie. stuck in loop.
我按照 这个 答案.
I navigate to LoginnFragment
using conditional navigation as per this answer.
如何正确实施?
推荐答案
这是 Ian Lake 在 Android 开发者 YouTube 频道上的导航导航视频".该解决方案基于导航 2.3 版本,其中引入了 能够将结果返回到之前的目的地.
Here's an official solution suggested by Ian Lake in Navigating navigation video at Jul 23, 2020 on Android Developers YouTube channel. The solution is based on navigation 2.3 release which introduced an ability to return a result to the previous destination.
在我们的例子中,登录片段将 LOGIN_SUCCESSFUL
状态返回到前一个目的地,它可能是配置文件片段或任何其他需要登录的片段.
In our case the login fragment returns LOGIN_SUCCESSFUL
state to the previous destination, it might be the profile fragment or any other fragment which requires login.
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.
The profile fragment subscribes to the LOGIN_SUCCESSFUL
state and processes it. Note that the observer lambda won't be called until the login fragment put a result in and return back to the profile fragment.
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
})
})
}
}
}
}
这篇关于导航架构组件 - 登录屏幕的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!