gpt4 book ai didi

android - 如何在可组合的屏幕中使用协同程序?

转载 作者:行者123 更新时间:2023-12-05 00:13:06 32 4
gpt4 key购买 nike

我正在使用 jetpack Compose and flow,但在尝试使用 LaunchedEffect 在可组合屏幕中获取数据时遇到错误
@Composable 的调用只能在 @Composable 函数的上下文中发生
这里我详细介绍了我的代码流程
在这里它会在 LaunchedEffect 中生成错误。
屏幕


@Composable
fun LoginScreen(
navController: NavController,
viewModel: LoginViewModel = hiltViewModel()
) {


Box(
modifier = Modifier.fillMaxSize().fillMaxHeight()
) {
Column(
modifier = Modifier.fillMaxWidth().padding(15.dp),
) {
//TextField username
//TextField password

Button(
onClick = {
// Error
// @Composable invocations can only happen from the context of a @Composable function
LaunchedEffect(Unit) {
viewModel.login(
viewModel.passwordValue.value, viewModel.usernameValue.value
)
}

},

) {
Text(text = stringResource(id = R.string.login))
}
}
}
}
View 模型
@HiltViewModel
class LoginViewModel @Inject constructor(private val toLogin: ToLogin) : ViewModel() {

private val _usernameValue = mutableStateOf("")
val usernameValue: State<String> = _usernameValue

private val _passwordValue = mutableStateOf("")
val passwordValue: State<String> = _passwordValue

fun setUsernameValue(username: String) {
_usernameValue.value = username
}

fun setPasswordValue(password: String) {
_passwordValue.value = password
}

suspend fun login(username: String, password: String) {

val r = toLogin(username, password);
r.collect {
Log.d("XTRACE", it.toString());
}

}
}
API
class AuthApiSource @Inject constructor(
private val loginApiService: LoginApiService,
) {
suspend fun login(username: String, password: String): Result<AccessToken?> = runCatching {

loginApiService.toLogin(
username = username,
password = password,
).body();

}
}
用例
class ToLogin @Inject constructor(private val apiAuth: AuthApiSource) {
operator fun invoke(username: String, password: String): Flow<Result<AccessToken?>> =
flow {
val response = runCatching {
val token = apiAuth.login(username, password)
token.getOrThrow()
}
emit(response)
}
}
正确的方法是什么?

最佳答案

您必须使用 rememberCoroutineScope :

@Composable
fun LoginScreen(
navController: NavController,
viewModel: LoginViewModel = hiltViewModel()
) {

val scope = rememberCoroutineScope()
Box(
modifier = Modifier.fillMaxSize().fillMaxHeight()
) {
Column(
modifier = Modifier.fillMaxWidth().padding(15.dp),
) {
//TextField username
//TextField password

Button(
onClick = {
// Error
// @Composable invocations can only happen from the context of a @Composable function
scope.launch {
viewModel.login(
viewModel.passwordValue.value, viewModel.usernameValue.value
)
}

},

) {
Text(text = stringResource(id = R.string.login))
}
}
}
}

关于android - 如何在可组合的屏幕中使用协同程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69186695/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com