我打算实施这样的导航:
我面临的问题是,当用户位于LoginFragmennt
中并按返回按钮时,它会再次加载LognFragment
,即。卡在循环中。
我根据this的答案使用条件导航导航到LoginnFragment
。
如何正确实施?
答案 0 :(得分:8)
恕我直言,我在应用程序中的操作方式更加简洁。只需将这些设置添加到导航图中:
<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当我们导航到ProfileFragment
时关闭LoginFragment
,因此,如果用户向后导航,它将退出应用程序。
答案 1 :(得分:5)
我可以提出的解决方案之一是在您的活动onBackPressed方法内部重写,并在您的当前目标位置(在进行后按操作之前)是登录片段的情况下完成活动。
<TextAreaField
name="summary"
label={{ id: 'Form.Summary' }}
maxLength={200}
rows={1}
readOnly={readOnly}
className={classes.join(" ")}
/>
答案 2 :(得分:1)
这是Ian Lake在2020年7月23日在Navigating navigation video YouTube频道上的Android Developers中提出的一种官方解决方案。该解决方案基于导航2.3 release,该导航将ability to return a result引入了先前的目的地。
在我们的情况下,登录片段将LOGIN_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
})
})
}
}
}
}