مؤشرات التقدم

تعرض مؤشرات التقدم حالة العملية بشكل مرئي. وهي تستخدم الحركة للفت انتباه المستخدم إلى مدى اقترابها من اكتمال العملية، مثل تحميل البيانات أو معالجتها. يمكنها أيضًا الإشارة إلى أن المعالجة تتم، دون الإشارة إلى مدى قُربها من الاكتمال.

ضع في اعتبارك حالات الاستخدام الثلاث هذه التي يمكنك فيها استخدام مؤشر التقدم:

  • تحميل المحتوى: أثناء جلب محتوى من إحدى الشبكات، مثل تحميل صورة أو بيانات لملف شخصي لمستخدم.
  • تحميل الملف: يجب تقديم ملاحظات للمستخدم حول المدة التي قد يستغرقها التحميل.
  • المعالجة الطويلة: أثناء معالجة تطبيق لكمية كبيرة من البيانات، أبلِغ المستخدم بمدى اكتمال معالجة البيانات.

في Material Design، هناك نوعان من مؤشرات التقدم:

  • التحديد: يعرض مقدار التقدم الذي تم إحرازه بالضبط.
  • غير محدَّد: تتم التحريك باستمرار بدون النظر إلى مستوى التقدّم.

وبالمثل، يمكن أن يتخذ مؤشر التقدم أحد الشكلين التاليين:

  • خطّي: شريط أفقي تتم تعبئته من اليسار إلى اليمين.
  • دائري: دائرة ينمو طولها إلى أن يشمل محيط الدائرة بالكامل.
مؤشر تقدم خطي إلى جانب مؤشر تقدم دائري.
الشكل 1. نوعا مؤشرات التقدم:

مساحة عرض واجهة برمجة التطبيقات

على الرغم من وجود العديد من العناصر القابلة للإنشاء التي يمكنك استخدامها لإنشاء أزرار إجراءات عائمة متوافقة مع Material Design، فإن معلماتها لا تختلف كثيرًا. من بين المعلمات الرئيسية التي ينبغي أن تضعها في اعتبارك ما يلي:

  • progress: التقدم الحالي الذي يعرضه المؤشر. عليك تمرير Float بين 0.0 و1.0
  • 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,
    )
}

في ما يلي مثال على هذا التنفيذ عندما يكون المؤشر نشطًا:

في ما يلي مثال على عملية التنفيذ نفسها ولكن باستخدام LinearProgressIndicator بدلاً من CircularProgressIndicator.

مراجع إضافية