导航架构组件 - 登录屏幕 [英] Navigation Architecture Component - Login screen

查看:24
本文介绍了导航架构组件 - 登录屏幕的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我打算实现这样的导航:

我面临的问题是当用户在 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆