نشانگرهای پیشرفت

نشانگرهای پیشرفت وضعیت عملیات را به‌صورت دیداری نشان می‌دهند. آن‌ها از حرکت استفاده می‌کنند تا توجه کاربر را به این جلب کنند که فرایند چقدر به تکمیل شدن نزدیک است، مثلاً بار کردن یا پردازش داده‌ها. همچنین می‌توانند نشان دهند که پردازش درحال انجام است، بدون اینکه اشاره‌ای به میزان تکمیل آن داشته باشند.

این سه مورد استفاده را که ممکن است در آن‌ها از نشانگر پیشرفت استفاده کنید درنظر بگیرید:

  • بار کردن محتوا: هنگام واکشی محتوا از شبکه، مثل بار کردن تصویر یا داده برای نمایه کاربر.
  • بارگذاری فایل: به کاربر بازخورد دهید که بارگذاری ممکن است چقدر طول بکشد.
  • پردازش طولانی: وقتی برنامه‌ای درحال پردازش حجم زیادی از داده‌ها است، به کاربر اطلاع دهید که چه مقدار از کل پردازش تکمیل شده است.

در «طراحی مواد»، دو نوع نشانگر پیشرفت وجود دارد:

  • مشخص: دقیقاً نشان می‌دهد چقدر پیشرفت حاصل شده است.
  • نامشخص: به‌طور مداوم و بدون توجه به پیشرفت، پویانمایی می‌شود.

به‌همین ترتیب، نشانگر پیشرفت می‌تواند یکی از دو شکل زیر را داشته باشد:

  • خطی: نوار افقی که از چپ به راست پر می‌شود.
  • دایره‌ای: دایره‌ای که طول خط آن افزایش می‌یابد تا کل محیط دایره را دربرگیرد.
نشانگر پیشرفت خطی در کنار نشانگر پیشرفت دایره‌ای.
شکل ۱. دو نوع نشانگر پیشرفت.

سطح API

اگرچه چندین ترکیب‌پذیر وجود دارد که می‌توانید برای ایجاد نشانگرهای پیشرفت سازگار با Material Design استفاده کنید، پارامترهای آن‌ها تفاوت چندانی ندارند. ازجمله پارامترهای کلیدی که باید درنظر داشته باشید موارد زیر است:

  • ‫progress: پیشرفت فعلی که نشانگر نمایش می‌دهد. Float را بین 0.0 و 1.0 پاس دهید.
  • ‫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 آورده شده است.

منابع بیشتر