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

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

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

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

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

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

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

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

سطح میانای برنامه‌سازی کاربردی

اگرچه چندین عنصر ترکیبی وجود دارد که می‌توانید برای ایجاد نشانگرهای پیشرفت سازگار با «طراحی مواد» استفاده کنید، پارامترهای آن‌ها تفاوت چندانی ندارد. ازجمله پارامترهای کلیدی که باید درنظر داشته باشید عبارت‌اند از:

  • 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 آمده است.

منابع بیشتر