진행 상태 표시기

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

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

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

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

  • 확정: 얼마나 진행되었는지 정확하게 표시합니다.
  • 미확정: 진행률과 관계없이 지속적으로 애니메이션이 적용됩니다.

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

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

API 노출 영역

Material Design과 일치하는 플로팅 작업 버튼을 만드는 데 사용할 수 있는 컴포저블이 여러 개 있지만 매개변수는 크게 다르지 않습니다. 유의해야 할 주요 매개변수는 다음과 같습니다.

  • 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를 사용합니다.

추가 리소스