我有一个带有
AsyncImage
的可组合函数,可以从服务器下载图像(我简化了函数以使其更容易理解):
@Composable
fun BannerReference(
modifier: Modifier = Modifier,
iconUrl: String? = null,
iconUrlFromRes: Int? = null,
onImageLoadingState: (State) -> Unit = {}
) {
SubcomposeAsyncImage(
modifier = Modifier
.height(110.dp)
.fillMaxSize(),
model = iconUrl,
contentScale = ContentScale.FillWidth,
alignment = Alignment.TopCenter,
onLoading = { onImageLoadingState.invoke(it) },
onSuccess = { onImageLoadingState.invoke(it) },
onError = { onImageLoadingState.invoke(it) },
error = {
Image(
painter = painterResource(id = iconUrlFromRes),
contentDescription = null,
contentScale = ContentScale.FillWidth,
alignment = Alignment.TopCenter
)
},
contentDescription = "SubscribePageImage",
)
}
因此有一个回调
onImageLoadingState
,我们在其中传递AsyncImagePainter
。状态密封类可以是Loading
、Success
和Error
。因此,我在另一个可组合函数中创建了多个 BannerReference
实例,并希望在其中至少一个的状态为 Loading
时添加加载程序。然后我在 Fragment
: 中创建这个屏幕
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? =
ComposeView(requireContext()).apply {
setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
setContent {
val state = viewModel.uiState.collectAsState()
ScreenWithSeveralBannerReferences(
state = state.value,
referralProgramsData = args.refData,
imageLoadingState = {
viewModel.sendAction(ReferralListActions.ImagesLoadingStatuses(it))
}
)
LaunchedEffect(Unit) {
viewModel.effect.collect { effect ->
handleEffect(effect)
}
}
}
}
最后我在
ViewModel
挂起函数中处理这些状态:
private suspend fun processImageLoadingStatus(imageLoadingState: ImageLoadingStatuses) {
imagesLoadingStatuses[imageLoadingState.index] = imageLoadingState.loadingState
_uiState.emit(
ReferralListState(
LoadingState(
showProgress = imagesLoadingStatuses.any { it.value is AsyncImagePainter.State.Loading },
isTransparent = true
)
)
)
}
问题是有时(我猜有加载错误时)下面的代码似乎无法正常工作,因为出现了无尽的加载程序。我认为当
BannerReference
的多个实例同时调用这些 onImageLoadingState
回调并且出现竞争条件(我不知道如何准确调用这种情况)并且一个或多个回调不执行时,就会发生这种情况。由于错误状态的回调不会被调用,所以加载器不会被隐藏。
onLoading = { onImageLoadingState.invoke(it) },
onSuccess = { onImageLoadingState.invoke(it) },
onError = { onImageLoadingState.invoke(it) },
请您告诉我如何处理同时调用 onImageLoadingState 并且有时似乎没有执行的情况?