Chỉ báo tiến trình

Chỉ báo tiến trình hiển thị trực quan trạng thái của một thao tác. Chúng sử dụng chuyển động để thu hút sự chú ý của người dùng về mức độ hoàn thành của quy trình, chẳng hạn như tải hoặc xử lý dữ liệu. Chúng cũng có thể cho biết rằng quá trình xử lý đang diễn ra, mà không đề cập đến mức độ hoàn tất.

Hãy xem xét 3 trường hợp sử dụng sau đây mà bạn có thể dùng chỉ báo tiến trình:

  • Tải nội dung: Trong khi tìm nạp nội dung từ một mạng, chẳng hạn như tải hình ảnh hoặc dữ liệu cho hồ sơ người dùng.
  • Tải tệp lên: Đưa ra ý kiến phản hồi cho người dùng về thời gian có thể mất để tải tệp lên.
  • Xử lý trong thời gian dài: Trong khi ứng dụng đang xử lý một lượng lớn dữ liệu, hãy cho người dùng biết đã hoàn thành bao nhiêu phần trăm tổng số.

Trong Material Design, có 2 loại chỉ báo tiến trình:

  • Xác định: Hiển thị chính xác tiến trình đã hoàn thành.
  • Không xác định: Hoạt ảnh liên tục mà không cần quan tâm đến tiến trình.

Tương tự, chỉ báo tiến trình có thể có một trong hai dạng sau:

  • Tuyến tính: Một thanh ngang lấp đầy từ trái sang phải.
  • Hình tròn: Một vòng tròn có nét vẽ tăng dần về độ dài cho đến khi bao trọn chu vi của vòng tròn.
Chỉ báo tiến trình tuyến tính cùng với chỉ báo tiến trình dạng xoay tròn.
Hình 1. Hai loại chỉ báo tiến trình.

Giao diện API

Mặc dù có một số thành phần kết hợp mà bạn có thể dùng để tạo chỉ báo tiến trình nhất quán với Material Design, nhưng các tham số của chúng không khác nhau nhiều. Sau đây là một số tham số chính bạn nên lưu ý:

  • progress: Tiến trình hiện tại mà chỉ báo hiển thị. Truyền một Float trong khoảng từ 0.0 đến 1.0.
  • color: Màu của chỉ báo thực tế. Tức là phần của thành phần phản ánh tiến trình và bao gồm toàn bộ thành phần khi tiến trình hoàn tất.
  • trackColor: Màu của đường mà chỉ báo được vẽ lên.

Chỉ báo xác định

Chỉ báo xác định phản ánh chính xác mức độ hoàn thành của một hành động. Sử dụng thành phần kết hợp LinearProgressIndicator hoặc CircularProgressIndicator và truyền một giá trị cho tham số progress.

Đoạn mã sau đây cung cấp một ví dụ tương đối chi tiết. Khi người dùng nhấn nút này, ứng dụng sẽ hiển thị chỉ báo tiến trình và khởi chạy một coroutine tăng dần giá trị của progress. Điều này khiến chỉ báo tiến trình lần lượt tăng lên.

@Composable
fun LinearDeterminateIndicator() {
    var currentProgress by remember { mutableStateOf(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)
    }
}

Khi quá trình tải hoàn tất một phần, chỉ báo tuyến tính trong ví dụ trước sẽ xuất hiện như sau:

Tương tự, chỉ báo hình tròn sẽ xuất hiện như sau:

Chỉ báo không xác định

Chỉ báo không xác định không phản ánh mức độ hoàn thành của một thao tác. Thay vào đó, chỉ báo này sử dụng chuyển động để cho người dùng biết rằng quá trình xử lý đang diễn ra, mặc dù không chỉ định mức độ hoàn thành nào.

Để tạo chỉ báo tiến trình không xác định, hãy dùng thành phần kết hợp LinearProgressIndicator hoặc CircularProgressIndicator, nhưng đừng truyền giá trị cho progress. Ví dụ sau đây minh hoạ cách bạn có thể bật/tắt chỉ báo không xác định bằng cách nhấn nút.

@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,
    )
}

Sau đây là ví dụ về cách triển khai này khi chỉ báo đang hoạt động:

Sau đây là ví dụ về cùng một cách triển khai nhưng dùng LinearProgressIndicator thay vì CircularProgressIndicator.

Tài nguyên khác