如何在 Jetpack Compose 中正确使用 Flow 和 ProgressBar?

Ioa*_* P. 1 android kotlin kotlin-coroutines android-jetpack-compose kotlin-flow

我有这段代码可以增加数据库中的值:

override fun incrementQuantity() = flow {
    try {
        emit(Result.Loading)
        heroIdRef.update("quantity", FieldValue.increment(1)).await()
        emit(Result.Success(true))
    } catch (e: Exception) {
        emit(Result.Failure(e))
    }
}
Run Code Online (Sandbox Code Playgroud)

该函数是从 ViewModel 类中调用的,然后从可组合函数中读取如下响应:

when(val response = viewModel.incrementResponse) {
    is Result.Loading -> showProgressBar()
    is Result.Success -> Log.d("TAG", "Quantity incremented.")
    is Result.Failure -> Log.d("TAG", response.e.message)
}
Run Code Online (Sandbox Code Playgroud)

这意味着在流程中我收到两个事件,第一个是Loading,第二个是数据或失败。我的问题是:

建议这样做吗?或者最好不使用流程并使用如下内容:

override fun incrementQuantity(): Result<Boolean> {
    try {
        heroIdRef.update("quantity", FieldValue.increment(1)).await()
        Result.Success(true)
    } catch (e: Exception) {
        Result.Failure(e)
    }
}
Run Code Online (Sandbox Code Playgroud)

在可组合项内部:

showProgressBar()
when(val response = viewModel.incrementResponse) {
    is Result.Success -> {
        hideProgressBar()
        Log.d("TAG", "Quantity incremented.")
    }
    is Result.Failure -> {
        hideProgressBar()
        Log.d("TAG", response.e.message)
    }
}
Run Code Online (Sandbox Code Playgroud)

使用 Kotlin 流程有什么缺点吗?

这是我的incrementResponse对象:

var incrementResponse by mutableStateOf<Response<Boolean>>(Response.Success(false))
    private set
Run Code Online (Sandbox Code Playgroud)

小智 5

在 jetpack compose 中,您不需要手动切换可见性。你可以和各州一起玩。您可以创建一个单独的进度条组件,也可用于其他屏幕。下面的代码只有在状态正在加载时才会被触发,如果状态发生变化,它将自动隐藏

@Composable
fun CircularIndeterminateProgressBar(
uiState: UiState
 ) {
if (uiState is UiState.Loading) {
    Column(
        modifier = Modifier.fillMaxSize(),
        verticalArrangement = Arrangement.Center,
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        CircularProgressIndicator()// provided by compose library 
    }
}
Run Code Online (Sandbox Code Playgroud)

}

然后从主屏幕可组合函数调用此组件并在其中传递状态

      CircularIndeterminateProgressBar(uiState = uiState)
        uiState you will get from viewmodel
Run Code Online (Sandbox Code Playgroud)

在视图模型中你将使用

   private val _uiState = mutableStateOf<ModelStateName>()
Run Code Online (Sandbox Code Playgroud)

上面是可变状态,它是生命周期感知的,将直接在可组合函数中列出

           val uiState by remember {
        viewmodel.uiState
    }
Run Code Online (Sandbox Code Playgroud)

在此处阅读有关可变状态的更多信息 jetpack compose中的可变状态

带有增量示例的 Jetpack 撰写研讨会 Jetpack 撰写研讨会