אינדיקטורים של התקדמות מציגים באופן חזותי את הסטטוס של פעולה. הם משתמשים בתנועה כדי להראות למשתמש כמה התהליך קרוב לסיום, למשל טעינה או עיבוד של נתונים. הם יכולים גם לציין שהעיבוד מתבצע, בלי להתייחס למידת הקרבה לסיום.
ריכזנו כאן שלושה תרחישים לדוגמה שכדאי להשתמש בהם במחוון התקדמות:
- טעינת תוכן: בזמן שליפת תוכן מרשת, כמו טעינת תמונה או נתונים לפרופיל משתמש.
- העלאת קבצים: כדאי לספק למשתמש משוב לגבי משך הזמן שיידרש להעלאה.
- עיבוד ארוך: בזמן שאפליקציה מעבדת כמות גדולה של נתונים, צריך להציג למשתמש כמה מהכמות הכוללת הושלמה.
ב-Material Design, יש שני סוגים של אינדיקטורים להתקדמות:
- קבוע: מוצג בדיוק כמה התקדמות נעשתה.
- לא מוגדר: האנימציה פועלת ללא הפסקה בלי קשר להתקדמות.
באופן דומה, מדד התקדמות יכול להופיע באחת משתי הצורות הבאות:
- לינארי: פס אופקי שמתמלא משמאל לימין.
- מעגלי: מעגל שהקו שלו מתארך עד שהוא מקיף את כל ההיקף של המעגל.
פלטפורמת ה-API
אפשר להשתמש בכמה רכיבים קומפוזביליים כדי ליצור אינדיקטורים של התקדמות שתואמים לעיצוב Material Design, אבל הפרמטרים שלהם לא שונים בהרבה. הנה כמה מהפרמטרים החשובים שכדאי לזכור:
-
progress: ההתקדמות הנוכחית שמוצגת באינדיקטור. מעביריםFloatבין0.0ל-1.0. -
color: הצבע של האינדיקטור בפועל. כלומר, החלק ברכיב שמשקף את ההתקדמות, שמקיף את הרכיב באופן מלא כשההתקדמות הושלמה. trackColor: הצבע של הרצועה שמעליה מצויר האינדיקטור.
אינדיקטורים קבועים
אינדיקטור קבוע משקף בדיוק את מידת ההשלמה של פעולה. אפשר להשתמש ברכיבי ה-Composable LinearProgressIndicator או CircularProgressIndicator ולהעביר ערך לפרמטר progress.
בקטע הקוד הבא מוצגת דוגמה מפורטת יחסית. כשמשתמש לוחץ על הכפתור, האפליקציה מציגה את אינדיקטור ההתקדמות ומפעילה שגרת המשך (coroutine) שמגדילה בהדרגה את הערך של progress. כתוצאה מכך, אינדיקטור ההתקדמות עובר איטרציה כלפי מעלה.
@Composable fun LinearDeterminateIndicator() { var currentProgress by remember { mutableFloatStateOf(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.