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