如何在创建 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
设置为导航图的起点。
我正在使用 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
设置为导航图的起点。