진행 상태 표시기

진행률 표시기는 작업 상태를 시각적으로 표시합니다. 모션을 사용하여 데이터 로드나 처리와 같은 프로세스가 얼마나 완료되었는지 사용자에게 알립니다. 또한 처리 완료 정도를 언급하지 않고 처리가 진행 중임을 나타낼 수도 있습니다.

진행률 표시기를 사용할 수 있는 세 가지 사용 사례를 고려해 보세요.

  • 콘텐츠 로드: 네트워크에서 콘텐츠를 가져오는 동안(예: 이미지 또는 사용자 프로필 데이터를 로드하는 동안)
  • 파일 업로드: 사용자에게 업로드에 걸리는 시간에 관한 의견을 제공합니다.
  • 처리 시간이 길음: 앱이 대량의 데이터를 처리하는 동안 사용자에게 전체 중 얼마나 완료되었는지 전달합니다.

Material Design에는 두 가지 유형의 진행률 표시기가 있습니다.

  • Determinate: 진행률을 정확하게 표시합니다.
  • Indeterminate: 진행 상황과 관계없이 계속 애니메이션이 재생됩니다.

마찬가지로 진행률 표시기는 다음 두 가지 형식 중 하나를 취할 수 있습니다.

  • 선형: 왼쪽에서 오른쪽으로 채워지는 가로 막대입니다.
  • 원형: 원의 전체 둘레를 포함할 때까지 획 길이가 늘어나는 원으로,
원형 진행률 표시기와 함께 선형 진행률 표시기
그림 1. 진행 상태 표시기의 두 가지 유형

API 노출 영역

머티리얼 디자인과 일치하는 진행률 표시기를 만드는 데 사용할 수 있는 여러 컴포저블이 있지만 매개변수는 크게 다르지 않습니다. 유의해야 할 주요 매개변수는 다음과 같습니다.

  • progress: 표시기가 표시하는 현재 진행률입니다. 0.01.0 사이의 Float를 전달합니다.
  • color: 실제 표시기의 색상입니다. 즉, 진행 상황을 반영하고 진행 상황이 완료되면 구성요소를 완전히 포함하는 구성요소의 일부입니다.
  • trackColor: 표시기가 그려지는 트랙의 색상입니다.

결정적 지표

결정적 표시기는 작업의 완료 정도를 정확하게 반영합니다. LinearProgressIndicator 또는 CircularProgressIndicator 컴포저블을 사용하고 progress 매개변수의 값을 전달합니다.

다음 스니펫은 비교적 자세한 예를 보여줍니다. 사용자가 버튼을 누르면 앱은 진행률 표시기를 표시하고 progress 값을 점진적으로 늘리는 코루틴을 실행합니다. 이렇게 하면 진행률 표시기가 차례로 위로 반복됩니다.

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

로드가 부분적으로 완료되면 위 예시의 선형 표시기가 다음과 같이 표시됩니다.

마찬가지로 원형 표시기는 다음과 같이 표시됩니다.

불확실한 표시기

불확정 표시기는 작업이 완료될 때까지 얼마나 남았는지 반영하지 않습니다. 대신 모션을 사용하여 처리가 진행 중임을 사용자에게 알리지만 완료 정도는 지정하지 않습니다.

불확정 진행률 표시기를 만들려면 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,
    )
}

다음은 표시기가 활성 상태일 때의 이 구현 예입니다.

다음은 동일한 구현이지만 CircularProgressIndicator 대신 LinearProgressIndicator를 사용하는 예입니다.

추가 리소스