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