在jetpack撰写中正确使用mutableStateflow与Launcheffect



嘿,我在MutableStateFlow在喷气背包撰写工作。我试图在下一个屏幕加载旋转器,但它不工作。我开始学习喷气背包作曲。我在喷气背包作曲中没有找到合适的方法。我知道MutableStateFlow在遗产的方式。我会试着解释我在努力做什么,我想要达到什么目标。我有一个按钮在可组合函数中,当我按下按钮时我要进入viewModel调用viewModelScope.launch内部的api。在此基础上,我创建了一个名为ResultFetchState的类这是密封类中,我使用了uistate。当我的api得到任何东西时,它将路由到成功,错误加载和. 主要问题是,当我使用collectAsState()的数据去onSuccess,但onLoading不工作。希望你能理解。

MainActivityViewModel.kt

class MainActivityViewModel(private val resultRepository: ResultRepository) : ViewModel() {
val stateResultFetchState = MutableStateFlow<ResultFetchState>(ResultFetchState.OnEmpty)
fun getSportResult() {
viewModelScope.launch {
val result = resultRepository.getSportResult()
delay(5000)
result.handleResult(
onSuccess = { response ->
if (response != null) {
stateResultFetchState.value = ResultFetchState.IsLoading(false)
stateResultFetchState.value = ResultFetchState.OnSuccess(response)
} else {
stateResultFetchState.value = ResultFetchState.OnEmpty
}
},
onError = {
stateResultFetchState.value =
ResultFetchState.OnError(it.errorResponse?.errorMessage)
}
)
}
}
}

我没有添加我的整个活动代码。我在添加可组合函数。如果你想看我的整个活动,点击下面的类名。

MainActivity.kt

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun SetupView(viewModel: MainActivityViewModel = koinViewModel()) {
Scaffold(topBar = {
TopAppBar(
title = { Text(text = stringResource(id = R.string.app_name)) },
backgroundColor = getBackgroundColor(),
elevation = 0.dp
)
}, content = { padding ->
Column(
modifier = Modifier
.fillMaxSize()
.background(getBackgroundColor())
.padding(padding),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Button(onClick = {
viewModel.getSportResult()
}) {
Text(text = stringResource(id = R.string.get_result))
}
}
})
when (val state = viewModel.stateResultFetchState.collectAsState().value) {
is ResultFetchState.OnSuccess -> {
logE("data >> ${state.sportResultResponse}")
}
is ResultFetchState.IsLoading -> {
if (state.isLoading) {
logE("data loading >")
ResultScreen()
}
}
is ResultFetchState.OnError -> {
logE("data >> ${state.response}")
}
is ResultFetchState.OnEmpty -> {}
}
}

我认为在我的生命周期中有问题。所以我搜索LaunchedEffect的堆栈溢出但还是不行。另一个问题是是否有LaunchedEffect的使用在我的代码中,我对这个副作用有点困惑。我的github项目链接。由于

您正在连续设置stateResultFetchState的值

fun getSportResult() {
viewModelScope.launch {
val result = resultRepository.getSportResult()
delay(5000)
result.handleResult(
onSuccess = { response ->
if (response != null) {
stateResultFetchState.value = ResultFetchState.IsLoading(false)
stateResultFetchState.value = ResultFetchState.OnSuccess(response)
} else {
stateResultFetchState.value = ResultFetchState.OnEmpty
}
},
onError = {
stateResultFetchState.value =
ResultFetchState.OnError(it.errorResponse?.errorMessage)
}
)
}
}

你可以设置为在获得体育结果之前加载,在你的ui中你检查是否加载为真,你需要设置为真

fun getSportResult() {
viewModelScope.launch {
stateResultFetchState.value = ResultFetchState.IsLoading(true)
val result = resultRepository.getSportResult()
delay(5000)
result.handleResult(
onSuccess = { response ->
if (response != null) {
stateResultFetchState.value = ResultFetchState.OnSuccess(response)
} else {
stateResultFetchState.value = ResultFetchState.OnEmpty
}
},
onError = {
stateResultFetchState.value =
ResultFetchState.OnError(it.errorResponse?.errorMessage)
}
)
}
}

你的UI也有问题。即使你正确地获得了加载状态,你也可能看到它们,因为Scaffold将contentComposable中的子元素放在了

之上
bodyContentPlaceables.forEach {
it.place(0, 0)
}

你可能需要使用可组合的,覆盖你的内容区域作为根Comopsable。

相关内容

  • 没有找到相关文章

最新更新