進度指標

進度指標會以視覺化方式呈現作業狀態。這類指標會透過動態效果,讓使用者注意到程序 (例如載入或處理資料) 即將完成。也可以表示正在處理,但不代表即將完成。

請考慮以下三種可能使用進度指標的情況:

  • 載入內容:從網路擷取內容時,例如載入圖片或使用者個人資料。
  • 檔案上傳:向使用者提供上傳所需時間的意見回饋。
  • 長時間處理:應用程式處理大量資料時,向使用者顯示已完成的總量。

在 Material Design 中,進度指標分為兩種類型:

  • 確定:顯示確切進度。
  • 不確定:持續播放動畫,不考慮進度。

同樣地,進度指標可以採用下列兩種形式之一:

  • 線性:由左至右填滿的水平列。
  • 圓形:圓形的筆劃長度會增加,直到涵蓋整個圓周。
線性進度指標和圓形進度指標。
圖 1. 兩種進度指標。

API 介面

雖然您可以使用多個可組合項,建立符合 Material Design 的進度指標,但這些指標的參數差異不大。請務必留意下列重要參數:

  • progress:指標顯示的目前進度。傳遞介於 0.0 和 1.0 之間的 Float。
  • color:實際指標的顏色。也就是反映進度的元件部分,在進度完成時會完全涵蓋元件。
  • trackColor:繪製指標的軌道顏色。

確定指標

確定指標會反映動作的完成程度。請使用 LinearProgressIndicator 或 CircularProgressIndicator 可組合項,並傳遞 progress 參數的值。

以下程式碼片段提供較詳細的範例。使用者按下按鈕後,應用程式會顯示進度指標,並啟動協同程式,逐步增加 progress 的值。這會導致進度指標依序向上疊加。

@Composable
fun LinearDeterminateIndicator() {
    var currentProgress by remember { mutableFloatStateOf(0f) }
    var loading by remember { mutableStateOf(false) }
    val scope = rememberCoroutineScope() // Create a coroutine scope

    Column(
        verticalArrangement = Arrangement.spacedBy(12.dp),
        horizontalAlignment = Alignment.CenterHorizontally,
        modifier = Modifier.fillMaxWidth()
    ) {
        Button(onClick = {
            loading = true
            scope.launch {
                loadProgress { progress ->
                    currentProgress = progress
                }
                loading = false // Reset loading when the coroutine finishes
            }
        }, enabled = !loading) {
            Text("Start loading")
        }

        if (loading) {
            LinearProgressIndicator(
                progress = { currentProgress },
                modifier = Modifier.fillMaxWidth(),
            )
        }
    }
}

/** Iterate the progress value */
suspend fun loadProgress(updateProgress: (Float) -> Unit) {
    for (i in 1..100) {
        updateProgress(i.toFloat() / 100)
        delay(100)
    }
}

載入作業部分完成時,上述範例中的線性指標會顯示如下:

同樣地,圓形指標會顯示如下:

未確定指標

不確定指標不會反映作業完成的進度,而是使用動作向使用者表示處理中,但不會指定任何完成程度。

如要建立不確定進度指標,請使用 LinearProgressIndicator 或 CircularProgressIndicator 可組合函式,但不要傳入 progress 的值。以下範例說明如何透過按下按鈕切換不確定指標。

@Composable
fun IndeterminateCircularIndicator() {
    var loading by remember { mutableStateOf(false) }

    Button(onClick = { loading = true }, enabled = !loading) {
        Text("Start loading")
    }

    if (!loading) return

    CircularProgressIndicator(
        modifier = Modifier.width(64.dp),
        color = MaterialTheme.colorScheme.secondary,
        trackColor = MaterialTheme.colorScheme.surfaceVariant,
    )
}

以下是指標啟用時的實作範例:

以下是相同實作範例,但使用 LinearProgressIndicator 而非 CircularProgressIndicator。

其他資源