我的状态为isLoading,当数值为true时,我try 显示为CircularProgressIndicator.

@Composable
fun ProductDetailScreen(
    viewModel: ProductDetailViewModel = hiltViewModel()
) {
    val productState = viewModel.productState.value
    LazyColumn{
        item {
            if (productState.isLoading)
                CircularProgressIndicator()
        }
    }
}

I'm using a Resource class for my API call results and in the repository I use this class to wrap my request result.
The problem is, although I'm returning Resource.Loading from the repository, the isLoading state is not being updated from ViewModel and the ProgressIndicator is not shown in my screen. What could be causing this behavior?

sealed class Resource<T>(
    val data: T? = null,
    val message: String? = null,
    val errorType: ExceptionMapper.Type? = null
) {
    class Success<T>(data: T?) : Resource<T>(data)
    class Error<T>(message: String, errorType: ExceptionMapper.Type, data: T? = null) : Resource<T>(data, message, errorType)
    class Loading<T>(isLoading: Boolean = true) : Resource<T>()
}  

Repository:

override suspend fun getProductComments(productId: Int): Resource<List<Comment>> {
        return try {
            Resource.Loading<List<Comment>>()
            delay(3000)
            Resource.Success(apiService.getComments(productId))
        } catch (t: Throwable) {
            val mappedException = ExceptionMapper.map(t)
            Resource.Error(message = t.message!!, errorType = mappedException.type)
        }
    }    

ViewModel:

@HiltViewModel
class ProductDetailViewModel @Inject constructor(
    state: SavedStateHandle,
    private val productRepository: ProductRepository
) : ViewModel() {

    private val passedProduct = state.get<Product>(EXTRA_KEY_DATA)
    var productId = passedProduct?.id

    var productState = mutableStateOf(ProductState())
        private set

    init {
        getProductComments()
    }
    private fun getProductComments() {
            viewModelScope.launch {
                productId?.let { pId ->
                    when (val commentResult = productRepository.getProductComments(pId)) {
                        is Resource.Success -> {
                            commentResult.data?.let { comments ->
                                productState.value =
                                    productState.value.copy(
                                        comments = comments,
                                        error = null,
                                        isLoading = false
                                    )
                            }
                        }
                        is Resource.Error -> {
                            productState.value = productState.value.copy(
                                isLoadFailed = true,
                                isLoading = false,
                                error = commentResult.message
                            )
                        }
                        is Resource.Loading -> {
                            productState.value = productState.value.copy(
                                isLoadFailed = false,
                                isLoading = true,
                                error = null
                            )
                        }
                    }
                }
            }
        }
}

推荐答案

你只是在判断这个

is Resource.Loading -> {
        ...
}

当存储库返回时,此时它毫无用处,因为当完成对getProductComments的调用时,它已经是Resource.Success了.

 return try {
      Resource.Loading<List<Comment>>() // you'll never get this value
      delay(3000)
      Resource.Success(apiService.getComments(productId))

所以我建议在你呼叫储存库之前更新ProductState

private fun getProductComments() {

      productState.value = productState.value.copy(isLoading = true)

      viewModelScope.launch {
      ...
      ...

或将isLoading设置为TRUE作为其初始状态.

data class ProductState(
     ...
     ...
     val isLoading : Boolean = true
     ...
)

Android相关问答推荐

Android可组合继承?

如何禁用Android 34+版的TileService,但保留以前的版本?

在Android上使用XSLT文件转换XML文件

strings.xml中字符串数组中的占位符

不能有意地从一个活动的可组合功能转移到另一个活动

Jetpack Compose-如何在进入新产品线之前删除单词?

如何使用 Wea​​r OS 上的运行状况服务模拟位置?

Jetpack Compose的val变量不能被重新分配

appcompat 依赖从何而来?

系统导航栏在某些场景下应用了深色效果

在 Jetpack Compose 的无状态 Compose 中管理条件逻辑

如何在 Jetpack Compose 中设置行宽等于 TextField 的宽度?

Jetpack Compose UI - 在 AlertDialog 中单击时按钮宽度会发生变化

react 从输入中找到路径'lib/arm64-v8a/libfbjni.so'的本机2个文件

我的观点在jetpack compose中相互重叠

JCenter 是否永久关闭(10 月 31 日)?

在alert 对话框生成器中启动协程

Jetpack 组合和片段

Kotlin Compose 全局页脚视图

升级到 android studio 花栗鼠后,应用程序未安装在模拟器中