Androidjetpack compose 登录时如何移动屏幕?

In Android jetpack compose, how to move the screen when I log in?

MainActivity

@AndroidEntryPoint
class MainActivity : ComponentActivity() {

    @Inject
    lateinit var connectivityManager: ConnectivityManager

    @Inject
    lateinit var settingsDataStore: SettingsDataStore

    override fun onStart() {
        super.onStart()
        connectivityManager.registerConnectionObserver(this)
    }

    override fun onDestroy() {
        super.onDestroy()
        connectivityManager.unregisterConnectionObserver(this)
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            val navController = rememberNavController()
                NavHost(
                    navController = navController,
                    startDestination = Screen.Login.route) {
                    composable(
                        route = Screen.Login.route
                    ) { navBackStackEntry ->
                        val factory = HiltViewModelFactory(LocalContext.current, navBackStackEntry)
                        val viewModel: LoginViewModel = viewModel(key = "LoginViewModel", factory = factory)
                        LoginScreen(
                            isNetworkAvailable = connectivityManager.isNetworkAvailable.value,
                            onNavigateToHomeScreen = navController::navigate,
                            viewModel = viewModel
                        )
                    }

                    composable(
                        route = Screen.Home.route
                    ) { navBackStackEntry ->
                        val factory = HiltViewModelFactory(LocalContext.current, navBackStackEntry)
                        val viewModel: HomeViewModel = viewModel(key = "HomeViewModel", factory = factory)

                        HomeScreen(

                        )
                    }
                }
        }
    }
}

登录屏幕

@Composable
fun LoginScreen(
    isNetworkAvailable: Boolean,
    onNavigateToHomeScreen: (String) -> Unit,
    viewModel: LoginViewModel
) {

    val loading = viewModel.loading.value
    val user = viewModel.user.value

    Scaffold(
        modifier = Modifier.fillMaxSize()
    ) {
        if (!loading && user == null) {
            Button(onClick = { viewModel.onTriggerEvent(LoginEvent.AuthStateEvent) }) {
                Column(

                ) {
                    Text(text = "Log in")
                }
            }
        }else {
            user?.let {
                val route = Screen.Home.route
                onNavigateToHomeScreen(route)
            }
        }
    }

}

LoginViewModel

@HiltViewModel
class LoginViewModel @Inject constructor(
    private val postLogin: PostLogin,
    private val connectivityManager: ConnectivityManager
) : ViewModel() {

    val user: MutableState<User?> = mutableStateOf(null)

    val loading = mutableStateOf(false)

    val onLoad: MutableState<Boolean> = mutableStateOf(false)

    fun onTriggerEvent(event: LoginEvent) {
        viewModelScope.launch {
            try {
                when(event) {
                    is LoginEvent.AuthStateEvent -> {
                        Log.d(TAG,"Phase 1")
                        if (user.value == null) {
                            val auth: Auth = Auth([***AuthData***])
                            postAuth(auth)
                        }
                    }
                }
            }catch (e: Exception) {
                Log.d(TAG, "launchJob: Exception: ${e}, ${e.cause}")
                e.printStackTrace()
            }
        }
    }

    private fun postAuth(auth: Auth) {
        Log.d(TAG,"Phase 2")
        postLogin.execute(auth, connectivityManager.isNetworkAvailable.value).onEach { dataState ->
            loading.value = dataState.loading

            dataState.data?.let { data ->
                user.value = data
                Log.d(TAG,"Phase 3")
                Log.d(TAG,"User Data File")
            }

            dataState.error?.let { error ->
                Log.d(TAG, "postAuth: ${error}")

            }
        }.launchIn(viewModelScope)
    }
}

登录事件

sealed class LoginEvent {

    object AuthStateEvent: LoginEvent()

}

登录后

class PostLogin(
    private val apiService: ApiService,
    private val authDtoMapper: AuthDtoMapper,
    private val userDtoMapper: UserDtoMapper
) {
    fun execute(
        auth: Auth,
        isNetworkAvailable: Boolean
    ): Flow<DataState<User>> = flow {
        //auth -> authDto -> InterActions -> userDto -> user
        try {
            emit(DataState.loading())
            delay(1000)

            if (isNetworkAvailable) {
                val networkUser = postLoginFromNetwork(auth)

                if (networkUser != null) {
                    emit(DataState.success(networkUser))
                }else {
                    emit(DataState.error<User>("User data is null"))
                }
            }else {
                emit(DataState.error<User>("Unable to connect network"))
            }

        }catch (e: Exception) {
            emit(DataState.error<User>(e.message?: "Unknown Error"))
        }
    }

    private suspend fun postLoginFromNetwork(auth: Auth): User {
        return userDtoMapper.mapToDomainModel(apiService.login(authDtoMapper.fromDomain(auth)))
    }
}

主屏幕

@Composable
fun HomeScreen() {
    Card(
        modifier = Modifier.fillMaxSize()
    ) {
        Column(
            modifier = Modifier.fillMaxSize(),
            horizontalAlignment = Alignment.CenterHorizontally,
            verticalArrangement = Arrangement.Center
        ) {
            Text(
                text = "HomeScreen",
                fontWeight = FontWeight.Bold,
                fontSize = 40.sp
            )
        }
    }
}

您好,我通过在 LoginScreen 上按 Login 按钮成功登录后将上面的代码转到 HomeScreen

确认沟通顺畅,也带来了价值

但是,当我尝试调试时,我确认这部分在登录屏幕上重复完成。

user?.let {
    val route = Screen.Home.route
    onNavigateToHomeScreen(route)
}

如您所见,当用户有一个值时,屏幕会移动,但那部分是重复完成的,所以 HomeScreen 屏幕像闪光一样闪烁。

这就是我问你这个问题的原因。沟通后数值改变时,请告诉我如何移动屏幕。

使用 LauchedEffect

LaunchedEffect(user){
   user.let {
      navController.navigate("")
    }
}