تعرض مؤشرات التقدم حالة عملية ما بشكل مرئي. تستخدم هذه المؤشرات الحركة لتنبيه المستخدم إلى مدى اقتراب العملية من الاكتمال، مثل تحميل البيانات أو معالجتها. ويمكن أن تشير أيضًا إلى أنّ عملية المعالجة قيد التنفيذ، بدون الإشارة إلى مدى اقترابها من الاكتمال.
إليك ثلاث حالات استخدام يمكنك فيها استخدام مؤشر التقدّم:
- تحميل المحتوى: أثناء جلب المحتوى من شبكة، مثل تحميل صورة أو بيانات لملف مستخدم
- تحميل الملف: قدِّم للمستخدم ملاحظات حول المدة التي قد يستغرقها التحميل.
- المعالجة الطويلة: أثناء معالجة التطبيق لكمية كبيرة من البيانات، يجب إعلام المستخدم بمقدار البيانات التي تمت معالجتها من إجمالي البيانات.
في Material Design، هناك نوعان من مؤشرات التقدم:
- محدّد: يعرض مقدار التقدّم الذي تم إحرازه بالضبط.
- غير محدّد: يتم تحريكه باستمرار بدون مراعاة مستوى التقدّم.
وبالمثل، يمكن أن يتّخذ مؤشر التقدم أحد الشكلَين التاليَين:
- خطي: شريط أفقي يمتلئ من اليسار إلى اليمين.
- دائري: دائرة يزداد طول خطها تدريجيًا إلى أن يشمل المحيط الكامل للدائرة.
مساحة واجهة برمجة التطبيقات
على الرغم من توفّر العديد من العناصر القابلة للإنشاء التي يمكنك استخدامها لإنشاء مؤشرات تقدّم متوافقة مع 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
.