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