如何在 Jetpack Compose 中的现有 LazyColumn 之上添加 CircularProgressIndicator?

Ioa*_* P. 2 android kotlin android-jetpack android-jetpack-compose

我有以下屏幕:

fun ItemsScreen(
    viewModel: ItemsViewModel = hiltViewModel()
) {
    val showProgressBarState = remember { mutableStateOf(false) }
    if (showProgressBarState.value) { ShowProgressBar() }

    when(val resource = viewModel.state.value) {
        is Loading -> ShowProgressBar() //Works perfectly
        is Success -> LazyColumn {
            items(
                items = resource.data
            ) { item ->
                ItemCard(
                    item = item
                )
            }
            when(val r = viewModel.s.value) {
                is Loading -> showProgressBarState.value = true
                is Success -> showProgressBarState.value = false
                is Failure -> Log.d(TAG, "Failure")
            }
        }
        is Failure -> Text(
            text = r.message,
            modifier = Modifier.padding(16.dp)
        )
    }
}

@Composable
fun ShowProgressBar() {
    Column(
        modifier = Modifier.fillMaxSize(),
        verticalArrangement = Arrangement.Center,
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        CircularProgressIndicator()
    }
}
Run Code Online (Sandbox Code Playgroud)

第二个“何时”用于删除状态。我希望当删除一个项目时启动进度条。它启动但位于 LazyColumn 后面。怎么加在前面呢?

这是我在活动课上的内容:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContent {
        Scaffold(
            //
        ) {
            ItemsScreen()
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Phi*_*hov 8

您正在视图生成器内更新状态值。在这种情况下它会起作用,但通常这是一种不好的做法,可能会导致冗余的重组,从而可能减慢您的应用程序的速度。我正在谈论这一部分:

when(val r = viewModel.s.value) {
    is Loading -> showProgressBarState.value = true
    is Success -> showProgressBarState.value = false
    is Failure -> Log.d(TAG, "Failure")
}
Run Code Online (Sandbox Code Playgroud)

您应该使用副作用来改变状态。在这里您可以使用LaunchedEffect,因此仅当自上次重组以来指定的键发生更改时才会调用内容。:

LaunchedEffect(viewModel.s.value) {
    when (val r = viewModel.s.value) {
        is Loading -> showProgressBarState.value = true
        is Success -> showProgressBarState.value = false
        is Failure -> Log.d(TAG, "Failure")
    }
}
Run Code Online (Sandbox Code Playgroud)

但实际上这是未来的一个题外话,在这种情况下你showProgressBarState根本不需要。

当您使用 时Box,项目会在屏幕上显示在彼此之上。由于您需要在 的 顶部显示进度条LazyColumn,因此需要用 包裹它Box并放在ShowProgressBar后面LazyColumn

您还可以指定contentAlignment = Alignment.Center而不是CircularProgressIndicator用 包装Column

is Resource.Success -> {
    Box(contentAlignment = Alignment.Center) {
        LazyColumn {
            items(
                items = resource.data
            ) { item ->
                ItemCard(
                    item = item
                )
            }
        }
        when (val r = viewModel.s.value) {
            is Resource.Loading -> CircularProgressIndicator()
            is Resource.Success -> Unit
            is Resource.Failure -> Log.d(TAG, "Failure")
        }
    }
}
Run Code Online (Sandbox Code Playgroud)