אתם יכולים להגדיר קונטיינר של רשת כדי ליצור פריסות גמישות שמתאימות לגדלים שונים של מסכים ולסוגי תוכן שונים. בדף הזה מוסבר איך:
- הגדרת רשת: מגדירים את המבנה הבסיסי של השורות והעמודות.
- הצבת פריטים ברשת: איך פריטים מוצבים בתאי רשת ואיך משנים את כיוון הזרימה.
- ניהול גודל המסלול: אפשר להגדיר את גודל המסלול באמצעות גודל קבוע, גודל באחוזים, גודל גמיש וגודל פנימי.
- הגדרת מרווחים: ניהול המרווחים בין השורות והעמודות.
הגדרת רשת (grid)
רשת מורכבת מעמודות ושורות.
לרכיב ה-Composable Grid יש פרמטר config שמקבל פונקציית lambda כדי להגדיר את העמודות והשורות בתוך GridConfigurationScope.
בדוגמה הבאה מוגדרת רשת עם שלוש שורות ושתי עמודות, שלכל אחת מהן יש גודל קבוע שצוין ב-Dp:
Grid( config = { repeat(2) { column(160.dp) } repeat(3) { row(90.dp) } } ) { }
הצבת פריטים ברשת
Grid לוקח את רכיבי ממשק המשתמש ב-lambda של content ומציב אותם בתאי רשת.
הרשת מסדרת את הפריטים גם אם לא הגדרתם במפורש את השורות והעמודות.
כברירת מחדל, Grid מנסה למקם רכיב בממשק המשתמש בתא רשת פנוי בשורה. אם אין תא פנוי, הוא ממקם אותו בתא רשת פנוי בשורה הבאה.
אם אין תאים ריקים, Grid יוצר שורה חדשה.
בדוגמה הבאה, ברשת יש שישה תאים, ובכל אחד מהם יש כרטיס (איור 1).
כל תא ברשת הוא בגודל 160dp x 90dp,
כך שהגודל הכולל של הרשת הוא 320dp x 270dp.
Grid( config = { repeat(2) { column(160.dp) } repeat(3) { row(90.dp) } } ) { Card1() Card2() Card3() Card4() Card5() Card6() }
כדי לשנות את התנהגות ברירת המחדל הזו למילוי לפי עמודה, מגדירים את המאפיין flow לערך GridFlow.Column.
Grid( config = { repeat(2) { column(160.dp) } repeat(3) { row(90.dp) } gap(8.dp) flow = GridFlow.Column // Grid tries to place items to fill the column }, ) { Card1() Card2() Card3() Card4() Card5() Card6() }
GridFlow.Row (משמאל) ו-GridFlow.Column (מימין).
ניהול גודל הטראק
שורות ועמודות נקראות ביחד מסלול רשת. אפשר לציין את הגודל של מסלול רשת באחת מהשיטות הבאות:
- קבוע (
Dp): הקצאת גודל ספציפי (למשל,column(180.dp)). - אחוז (
Float): מקצה אחוז מסוים מהשטח הכולל שזמין מ-0.0fעד1.0f(למשל,row(0.5f)ל-50%). - גמיש (
Fr): חלוקה של המקום שנותר באופן יחסי אחרי חישוב הטראקים הקבועים והטראקים באחוזים. לדוגמה, אם שתי שורות מוגדרות ל-1.frול-3.fr, השורה השנייה מקבלת 75% מהגובה שנותר. - פנימי: קובע את גודל המסלול לפי התוכן שבתוכו. מידע נוסף זמין במאמר קביעת גודל הרצועה של הרשת באופן פנימי.
בדוגמה הבאה נעשה שימוש באפשרויות השונות של גודל המסלול כדי להגדיר את גובה השורות:
Grid( config = { column(1f) row(100.dp) row(0.2f) row(1.fr) row(GridTrackSize.Auto) }, modifier = Modifier.height(480.dp) ) { PastelRedCard("Fixed(100.dp)") PastelGreenCard("Percentage(0.2f)") PastelBlueCard("Flex(1.fr)") PastelYellowCard("Auto") }
Grid.
הגדרת הגודל המינימלי של מסלולי רשת גמישים
כשאין יותר מקום פנוי בקונטיינר של הרשת,
מסלול גמיש רגיל יכול להתכווץ ל-0.dp.
כדי למנוע את זה ולוודא שהתוכן לא נדחס, משתמשים ב-GridTrackSize.MinMax כדי לאכוף גודל מינימלי מפורש תוך שמירה על הגמישות של המסלול.
בדוגמה הבאה, מוקצים לפחות 100.dp לשורה הראשונה:
Grid( config = { column(1f) // The first row has a minimum height of 100.dp and can expand to // the half of the remaining space. row(GridTrackSize.MinMax(100.dp, 1.fr)) // The second row takes the half of the remaining space. row(1.fr) // The third row has a fixed height of 200.dp. row(200.dp) }, modifier = Modifier.size(360.dp) // Total grid height is 360.dp ) { PastelRedCard("MinMax(100.dp, 1.fr)") PastelGreenCard("Flex(1.fr)") PastelBlueCard("Fixed(200.dp)") }
100.dp.
הגדרת הגודל המינימלי של טראק הרשת כדי להציב רשימות בטעינה מדורגת
מסלולים גמישים רגילים שולחים שאילתות באופן אוטומטי לגבי הגדלים הפנימיים של הצאצאים שלהם כדי לקבוע גודל בסיס.
עם זאת, ב-Jetpack Compose אסור לשלוח שאילתות לגבי הגדלים הפנימיים של SubcomposeLayout, שתומך ברכיבים כמו LazyColumn ו-LazyRow.
אם ממקמים רשימה בטעינה מדורגת בתוך מסלול גמיש רגיל, זה גורם לקריסה של IllegalStateException.
כדי להציב בבטחה רשימות בטעינה מדורגת בתוך מסלול גמיש של רשת,
צריך להשתמש ב-MinMax עם גודל מינימלי מפורש (כמו 0.dp)
כדי לעקוף את שלב המדידה הפנימית.
Grid( config = { column(1f) // The first row's height is determined by the height of the Text composable. row(GridTrackSize.Auto) // The second row occupies the remaining space, allowing the LazyColumn to scroll. row(GridTrackSize.MinMax(0.dp, 1.fr)) gap(8.dp) }, modifier = Modifier.size(width = 170.dp, height = 240.dp) ) { Text("LazyColumn in a Grid") // The LazyColumn is placed in the second row, filling the remaining space. LazyColumn(verticalArrangement = Arrangement.spacedBy(4.dp)) { items(100) { number -> PastelGreenCard("Card $number") } } }
LazyColumn בתא רשת.
קביעת גודל המסלול של הרשת באופן פנימי
אפשר להשתמש בגודל פנימי של Grid
כדי שהפריסה תתאים לתוכן,
במקום לאלץ אותו להיכנס למאגר קבוע.
גודל הרצועה של הרשת נקבע לפי הערכים הבאים:
-
GridTrackSize.MaxContent: שימוש בגודל המקסימלי של התוכן (לדוגמה, הרוחב נקבע לפי האורך המלא של הטקסט בבלוק טקסט בלי גלישת טקסט). -
GridTrackSize.MinContent: שימוש בגודל המינימלי של התוכן (לדוגמה, הרוחב נקבע לפי המילה הארוכה ביותר בבלוק טקסט). -
GridTrackSize.Auto: שימוש בגודל גמיש של טראק שמשתנה בהתאם למקום הפנוי. כברירת מחדל, הוא מתנהג כמוMaxContent, אבל מכווץ את התוכן שלו ועוטף אותו כדי שיתאים למאגר ההורה.
בדוגמה הבאה, שני טקסטים מוצגים זה לצד זה. גודל העמודה של הטקסט הראשון נקבע לפי הרוחב המינימלי שנדרש כדי להציג את הטקסט, ורוחב העמודה השנייה תלוי ברוחב המקסימלי שנדרש לטקסט.
Grid( config = { column(GridTrackSize.MinContent) column(GridTrackSize.MaxContent) row(1.0f) }, modifier = Modifier.width(480.dp) ) { Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras imperdiet.") Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras imperdiet.") }
הגדרת מרווחים בין שורות ועמודות
אחרי שקובעים את הגודל של מסלולי הרשת, אפשר לשנות את המרווחים ברשת כדי לשפר את המרווחים בין המסלולים.
אפשר לציין את המרווח בין העמודות באמצעות הפונקציה columnGap, ואת המרווח בין השורות באמצעות הפונקציה rowGap. בדוגמה הבאה, יש מרווח של 16dp בין כל שורה, ומרווח של 8dp בין כל עמודה (איור 5).
Grid( config = { repeat(2) { column(160.dp) } repeat(3) { row(90.dp) } rowGap(16.dp) columnGap(8.dp) } ) { Card1() Card2() Card3() Card4() Card5() Card6() }
אפשר גם להשתמש בפונקציה הנוחה gap כדי להגדיר מרווחים באותו גודל של עמודה ושורה, ולהגדיר גדלים של עמודות ומרווחים בנפרד באמצעות פונקציה אחת.
הקוד הבא מוסיף מרווחים של 8dp לרשת:
Grid( config = { repeat(2) { column(160.dp) } repeat(3) { row(90.dp) } gap(8.dp) // Equivalent to columnGap(8.dp) and rowGap(8.dp) } ) { Card1() Card2() Card3() Card4() Card5() Card6() }
הגדרת אזורים ברשת באמצעות אזורים בעלי שם
אזורים עם שמות מאפשרים לכם לצרף שמות לקבוצות של תאים ברשת, שנקראים אזורי רשת. אתם יכולים להשתמש בשמות האלה במקום באינדקסים של קואורדינטות כשאתם ממקמים רכיב בממשק המשתמש ברשת.
שימוש באזורים בעלי שם משפר את קריאוּת הקוד בשתי דרכים עיקריות:
- כשמגדירים את פריסת הרשת, המטרה והמיקום של התוכן הצפוי ברורים.
- כשמוסיפים את התוכן, המטרה שלו ברורה.
כדי לארגן פריסות מורכבות בצורה ברורה, אתם יכולים להפריד בין מבנה הרשת הפיזי לבין מיקום הצאצאים על ידי הגדרת אזורי רשת סמנטיים.
בתוך פונקציית הלמבדה config, משתמשים בפונקציה area ב-GridConfigurationScope כדי לרשום אזורים בעלי שם ברשת.
לאחר מכן, אפשר להקצות רכיבים קומפוזביליים צאצאים לאזורים האלה באמצעות המשתנה gridItem עם המזהה של האזור המתאים. הפונקציה area ממפה מזהה סמנטי (כמו ערך של מחלקה enum או מפתח מחרוזת) לקבוצה של קואורדינטות רשת פיזיות. קווי הרשת והאינדקסים מבוססים על 1 (כלומר, השורה הראשונה היא 1 והעמודה הראשונה היא 1).
לדוגמה, אתם מגדירים רשת עם ארבעה מזהי אזורים:
/** * An enum representing the IDs for named areas within the grid. */ enum class GridAreaNames { Area1, Area2, Area3, Area4 }
מציינים את שם האזור באמצעות הפרמטר areaId, יחד עם הקואורדינטות והטווחים של התאים באזור.
המשתנה gridItem משתמש ב-areaId כמפתח כדי להקצות כל פריט צאצא לאזור הרשת המיועד שלו, כמו שמוצג בדוגמה הבאה:
Grid( config = { // Define a single column that takes all available width. repeat(2) { column(0.5f) } // Define four rows, each taking 25% of the total height. repeat(4) { row(0.25f) } // Define named grid areas by associating an areaId with specific row and column indices. // Row and column indices are 1-based. area(areaId = GridAreaNames.Area1, row = 1, column = 1, columnSpan = 2) area(areaId = GridAreaNames.Area2, row = 2, column = 1, rowSpan = 3) area(areaId = GridAreaNames.Area3, rows = 2..3, columns = 2..2) area(areaId = GridAreaNames.Area4, row = 4, column = 2) gap(4.dp) }, modifier = Modifier.size(360.dp) ) { PastelRedCard( "Area 1", // Use Modifier.gridItem(areaId) to place this composable into the // grid area defined with the matching ID in the config block. modifier = Modifier.gridItem(areaId = GridAreaNames.Area1) ) PastelGreenCard( "Area 2", modifier = Modifier.gridItem(areaId = GridAreaNames.Area2) ) PastelBlueCard( "Area 3", modifier = Modifier.gridItem(areaId = GridAreaNames.Area3) ) PastelYellowCard( "Area 4", modifier = Modifier.gridItem(areaId = GridAreaNames.Area4) ) }
באמצעות אזורים עם שם, אתם יכולים לארגן מחדש או לשנות את פריסת הרשת הפיזית (לדוגמה, לשנות שורות, עמודות או גדלים של טראקים) ב-lambda של config בלי לשנות את הסדר או הפרמטרים של רכיבי ה-Composable הצאצאים.