如何在创建 activity 的 UI 之前使用 addOnDestinationChangedListener 更改导航组件的目标?

How to change Navigation Component's Destination with addOnDestinationChangedListener before the activity's UI is created?

我正在使用 google 推荐的 SingleActivity 模式开发应用程序。我的场景是:我的应用程序从 HomeFragment 的 startDestination 开始。如果用户未登录,我想从 LoginFragment 开始。我的逻辑是我将登录状态保存在 DataStore 中,该状态最初为 false。当我的应用程序开始启动时。在我的 MainActivity 中,我通过 ViewModel 观察了登录状态。然后我将该状态传递给一个函数。这是我的职能。

private fun setDestinationForApp(isLoggedIn: Boolean) {
    navController.addOnDestinationChangedListener { _, destination, _ ->
        if (destination.id == R.id.dest_home) {
            if (!isLoggedIn) {
                val authNavOptions = NavOptions.Builder()
                    .setPopUpTo(R.id.dest_home, true)
                    .build()
                navController.navigate(R.id.action_home_to_login, Bundle(), authNavOptions)

            }
        }
    }
}

这样就好了。但我面临的是:我的应用程序开始显示 HomeFragment 默认值,然后如果用户未登录,则转到 LoginFragment。

I want to display corresponding destination fragment according to my loggedIn status from DataStore. Not want to display the default HomeFragment first.

这可能是 Activity 生命周期和导航组件回调侦听器。但我不够聪明。请帮助我,我陷入了困境。如果我的问题不清楚或无法解决。请帮我找到合适的方法。

这是我的全部Activity。

@AndroidEntryPoint
class MainActivity : BaseActivity<ActivityMainBinding>(ActivityMainBinding::inflate) {

private val navHostFragment: NavHostFragment by lazy {
    supportFragmentManager.findFragmentById(R.id.container) as NavHostFragment
}
private val navController: NavController by lazy {
    navHostFragment.navController
}
private val appBarConfiguration: AppBarConfiguration by lazy {
    AppBarConfiguration(navController.graph)
}

private val loadingDialog: LoadingDialog by lazy { LoadingDialog(this) }

private val viewModel: MainViewModel by viewModels()

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setupNavigation()
}

override fun observe() {
    super.observe()
    lifecycleScope.launchWhenCreated {
        viewModel.authState.collect {
            setDestinationForApp(it)
        }
    }
}

private fun setupNavigation() {
    setSupportActionBar(binding.authToolbar)
    setupActionBarWithNavController(navController, appBarConfiguration)
}

override fun onSupportNavigateUp(): Boolean {
    return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp()
}

fun showLoadingDialog(text: String) {
    loadingDialog.apply {
        setMessage(text)
        setCanceledOnTouchOutside(false)
        setCancelable(false)
        show()
    }
}

fun hideLoadingDialog() {
    loadingDialog.hide()
}

private fun setDestinationForApp(isLoggedIn: Boolean) {
    navController.addOnDestinationChangedListener { _, destination, _ ->
        if (destination.id == R.id.dest_home) {
            if (!isLoggedIn) {
                val authNavOptions = NavOptions.Builder()
                    .setPopUpTo(R.id.dest_home, true)
                    .build()
                navController.navigate(R.id.action_home_to_login, Bundle(), authNavOptions)

            }
        }
    }
}

}

这是因为导航组件以起始图片段开始。不管怎样,如果您想从 LoginFragment 返回。它回到 HomeFragment。因此,在这种情况下,您需要检查启动过程中的登录状态,如果用户未登录,您可以通过编程方式更改图形的起点。这样起点将是 LoginFragment,它永远不会导航到 HomeFragment。在登录过程之后,您可以恢复此逻辑以将 HomeFragment 设置为导航图的起点。