我有一个API“breedImageByID(referenceImageId:String)”,它依赖于“getBreeds()”API来获取referenceImageId。获取数据后,我需要使用 getBreeds 数据和 BreedImageByID() 数据填充列表中的每个项目。但执行此操作后,它的行为很奇怪,breedImageByID() 图像无法与 getBreed() 数据正确对齐以填充列表中的每个项目。我该如何解决这个问题。
品种筛选:
@Composable
fun BreedListItem(
breed: BreedItem,
catImage: CatImage,
viewModel: BreedSharedViewModel,
navController: NavController
) {
val breedImageURL = remember {
breed.reference_image_id.let { imageId ->
viewModel.breedImageByID.value.data?.url ?: ""
}
}
Row(
modifier = Modifier
.fillMaxSize()
.padding(6.dp)
.clip(RoundedCornerShape(18.dp))
.background(Color.Gray)
.clickable {
viewModel.addBreedItem(breed)
navController.navigate(DetailsNavScreen.BreedsDetail.route)
},
verticalAlignment = Alignment.CenterVertically
) {
Row(
modifier = Modifier
.width(120.dp)
.height(80.dp)
.clip(RoundedCornerShape(12.dp))
) {
SubcomposeAsyncImage(
model = breedImageURL,
contentDescription = null,
contentScale = ContentScale.FillBounds
)
}
Text(
text = breed.name,
modifier = Modifier.padding(start = 15.dp),
fontWeight = FontWeight.ExtraBold,
fontSize = 17.sp
)
}
Spacer(modifier = Modifier.height(10.dp))
}
BreedSharedViewModel:
val breeds: MutableState<NetworkResult<GetBreeds>> =
mutableStateOf(NetworkResult.Loading())
val breedImageByID: MutableState<NetworkResult<CatImage>> =
mutableStateOf(NetworkResult.Loading())
private fun getBreeds() = viewModelScope.launch {
repository.getBreeds().collect { values ->
breeds.value = values
values.data?.forEach {
it.reference_image_id?.let { imageId ->
breedImageByID(imageId)
breedImageByID.value.data?.let {
it1 ->
Log.i("catImageID", it1.url)
}
}
}
}
}
fun breedImageByID(referenceImageId: String) = viewModelScope.launch {
repository.getCatImageByID(referenceImageId).collect { values ->
breedImageByID.value = values
}
}
launch
、async
是 kotlin 中可用的协程构建器。 launch
函数遵循 fire and forget
方法,这本质上意味着它将启动一个协程并忘记其结果。而 aync
返回 Deferred
的实例,它具有名为 await
的函数,可用于等待结果。在协程构建器中,您可以创建多个不一定同步的协程。您在这里尝试做的事情也是一样的。当您调用 breedImageByID
时,您启动了另一个协程,它不会等待其结果。要使其同步,请尝试如下await
suspend fun breedImageByID(referenceImageId: String) = viewModelScope.async {
repository.getCatImageByID(referenceImageId)
}.await()
请注意,我在函数定义之前添加了
suspend
关键字。另请确保 getCatImageByID
是 suspend
函数。上面的代码对每个猫图像 ID 进行网络调用以进行繁殖。