רשימות עצלניות בפריסת רשת

סמל של דירוג ארבעה כוכבים

רכיב ה-Composable‏ Grid יוצר פריסות מסך דו-ממדיות ומבניות. ‫Grid מגדיר מבנה פריסה רספונסיבי באמצעות טראקים (שורות ועמודות) ורווחים שהוגדרו במפורש, כארכיטקטורה הבסיסית של ממשק המשתמש.

Grid הוא קונטיינר מבני ולא קונטיינר לטעינה עצלה, ולכן צריך להגדיר במפורש כל אלמנט שמוצב בתוכו בלי למחזר פריטים בגלילה. כתוצאה מכך, עיבוד של מערכי נתונים גדולים או דינמיים ישירות בתוך Grid עלול לגרום לצווארי בקבוק בביצועים, כי כל הפריטים מורכבים בו-זמנית.

כדי להציג אוספים גדולים של נתונים בפריסת מסך מובנית, מטמיעים רכיבים עצלים כמו LazyColumn או LazyRow בתאי Grid. אבל חשוב לזכור: רכיבים גמישים (עם הגדרות כמו 1.fr) שולחים שאילתות לגבי הגדלים הפנימיים של רכיבי צאצא. מכיוון ש-SubcomposeLayout לא תומך במעברים של מדידה פנימית, הצבת רשימה עצלה בתוך מסלול גמיש גורמת לקריסה של IllegalStateException. כדי למקם בבטחה רשימות עצלות בתוך רצועת רשת גמישה, צריך להשתמש בגודל GridTrackSize.MinMax (כמו minmax(0.dp, 1.fr)) כדי לעקוף את שלב המדידה המובנה.

פריסת המסך עם כותרת עליונה בחלק העליון, רשימה של פריטים שאפשר לגלול בהם באזור התוכן הראשי וכותרת תחתונה בחלק התחתון.
איור 1. פריסת מסך מבנית עם כותרת, כותרת תחתונה וLazyColumn תוכן מוטמע.

שיטות מומלצות

  • שימוש ברשימות עצלות במקום בלולאות גדולות וספציפיות: כדי להציג מערכי נתונים גדולים או דינמיים בתוך רכיב Grid מובנה, מטמיעים רכיבים עצלים (בדרך כלל LazyColumn או LazyRow) בתוך תאים ספציפיים של רשת, במקום ליצור לולאות גדולות וספציפיות של פריטים, כי רכיב Grid לא ממחזר פריטים ויש לו מגבלה של 1,000 רצועות.
  • שימוש ב-MinMax track sizing לרשימות עצלות: מכיוון ש-LazyColumn ו-LazyRow לא תומכים במעברים של מדידות פנימיות (ראו SubcomposeLayout), צריך להשתמש ב-GridTrackSize.MinMax ברכיבים עצלים שמתארחים בטראקים גמישים כדי לעקוף את המדידות הפנימיות בצורה בטוחה.

אלמנטים

  • Grid: פריסה קומפוזבילית שמציבה פריטים במבנה רשת דו-ממדי שמוגדר באמצעות עקבות שורה ועמודה מפורשים.
  • LazyColumn: רשימה עם גלילה אנכית שכוללת רק את הפריטים שמוצגים כרגע במסך, ומשתמשת בהם מחדש.
  • GridTrackSize.MinMax: מאפיין של גודל הרכיב שקובע גבולות גמישים (min ו-max) כדי לארח בבטחה רכיבים שנטענים באיחור בלי לגרום לקריסות של מדידת זמן הריצה.
  • gridItem: התוסף Compose Modifier שמקצה רכיב בממשק המשתמש צאצא לתא ספציפי או לאזור עם שם בתוך Grid.

צעדים

כדי להגדיר את פריסת המסך, מגדירים מזהים סמנטיים של אזורים, מגדירים רכיבי grid track עם minmax sizing כדי להבטיח תאימות לרשימות עצלות, ומטמיעים LazyColumn באזור התוכן של ה-grid.

‫1. הגדרת שורות ברשת ואזורים ששמותיהם מופיעים ברשת

יוצרים מחלקה enum שמייצגת את האזורים השונים בפריסת המסך, ומגדירים פונקציית למדה GridConfigurationScope עבור רצועות הפריסה והאזורים עם השמות. משתמשים ב-GridTrackSize.MaxContent בשורות של הכותרת העליונה והכותרת התחתונה כדי להתאים את מידות התוכן שלהן, וב-minmax(0.dp, 1.fr) בשורת התוכן שמארחת את הרשימה העצלנית כדי להקצות מקום גמיש בלי לשלוח שאילתה לגבי מדידות פנימיות לא נתמכות:

enum class ScreenArea {
    Header,
    Content,
    Footer
}


val lazyConfig: GridConfigurationScope.() -> Unit = {
    column(minmax(0.dp, 1.fr))
    row(GridTrackSize.MaxContent)
    row(minmax(0.dp, 1.fr))
    row(GridTrackSize.MaxContent)

    area(ScreenArea.Header, row = 1, column = 1)
    area(ScreenArea.Content, row = 2, column = 1)
    area(ScreenArea.Footer, row = 3, column = 1)
    gap(8.dp)
}

2. מיקום רכיבים סטטיים ברשת

ב-composable, מעבירים את lazyConfig אל מאגר התגים Grid. בתוך פונקציית ה-lambda‏ content, ממקמים רכיבים סטטיים (Header ו-Footer) וממקמים אותם באמצעות Modifier.gridItem() עם מזהי האזור המתאימים.

3. הטמעה של LazyColumn באזור התוכן

בתא התוכן, מטמיעים את LazyColumn באמצעות Modifier.gridItem(ScreenArea.Content). הגדרנו את רכיב התוכן עם minmax(0.dp, 1.fr) בשלב 1, ולכן LazyColumn יכול למדוד בבטחה פריטים ולמחזר אותם בגלילה בלי לשלוח שאילתות לגבי מאפיינים פנימיים לא נתמכים:

@Composable
fun GridWithLazyColumn(
    modifier: Modifier = Modifier,
    items: List<String> = emptyList(),
) {
    Grid(
        modifier = modifier.fillMaxSize(),
        config = lazyConfig
    ) {
        Text("Header", Modifier.gridItem(ScreenArea.Header).padding(16.dp))
        Text("Footer", Modifier.gridItem(ScreenArea.Footer).padding(16.dp))

        // LazyColumn placed in the content area for large datasets
        LazyColumn(
            modifier = Modifier
                .gridItem(ScreenArea.Content)
                .fillMaxSize(),
            verticalArrangement = Arrangement.spacedBy(8.dp)
        ) {
            items(items) { item ->
                Text(item, Modifier.padding(16.dp))
            }
        }
    }
}

תוצאות

פריסת המסך שלכם משתמשת עכשיו ב-API‏ Grid כדי להגדיר את המבנה הדו-ממדי הכולל של הדף, תוך הטמעה של LazyColumn במסלול גמיש עם minmax שינוי גודל כדי למחזר פריטים ברשימה בצורה יעילה ולהימנע מחריגות בזמן ריצה.

מקורות מידע נוספים