בניית פריסה של רשימה ופירוט

תבנית list-detail היא תבנית של ממשק משתמש שמורכבת מפריסה של שתי חלוניות. בחלונית אחת מוצגת רשימה של פריטים, ובחלונית השנייה מוצגים הפרטים של הפריטים שנבחרו מהרשימה.

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

חלונית פרטים שמוצגת לצד דף הרשימה.
איור 1. אם יש מספיק מקום במסך, חלונית הפרטים מוצגת לצד חלונית הרשימה.
אחרי שבוחרים פריט, חלונית הפרטים תופסת את כל המסך.
איור 2. כשגודל המסך מוגבל, חלונית הפרטים (מאחר שנבחר פריט) תופסת את כל המקום.

הטמעה של תבנית רשימה עם פרטים באמצעות NavigableListDetailPaneScaffold

NavigableListDetailPaneScaffold הוא קומפוזיציה שמפשטת את ההטמעה של פריסת רשימה עם פרטים ב-Jetpack פיתוח נייטיב. הוא עוטף את ListDetailPaneScaffold ומוסיף ניווט מובנה ואנימציות של חיזוי תנועת החזרה.

פיגום של רשימה עם פרטים תומך בעד שלושה חלוניות:

  1. חלונית הרשימה: מוצג בה אוסף של פריטים.
  2. חלונית הפרטים: מוצגים בה הפרטים של פריט שנבחר.
  3. חלונית נוספת (אופציונלית): מספקת הקשר נוסף כשצריך.

הפיגום מותאם בהתאם לגודל החלון:

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

הצהרה על יחסי תלות

NavigableListDetailPaneScaffold הוא חלק מספריית הניווט הדינמי Material 3.

מוסיפים את שלושת יחסי התלות הקשורים הבאים לקובץ build.gradle של האפליקציה או המודול:

Kotlin

implementation("androidx.compose.material3.adaptive:adaptive")
implementation("androidx.compose.material3.adaptive:adaptive-layout")
implementation("androidx.compose.material3.adaptive:adaptive-navigation")

גרוב

implementation 'androidx.compose.material3.adaptive:adaptive'
implementation 'androidx.compose.material3.adaptive:adaptive-layout'
implementation 'androidx.compose.material3.adaptive:adaptive-navigation'
  • אדפטיבי: אבני בניין ברמה נמוכה כמו HingeInfo ו-Posture
  • ‫adaptive-layout: פריסות מותאמות כמו ListDetailPaneScaffold ו-SupportingPaneScaffold
  • adaptive-navigation: רכיבי Composable לניווט בתוך חלוניות וביניהן, וגם פריסות דינמיות שתומכות בניווט כברירת מחדל, כמו NavigableListDetailPaneScaffold ו-NavigableSupportingPaneScaffold

מוודאים שהפרויקט כולל את compose-material3-adaptive בגרסה 1.1.0-beta1 ואילך.

הצטרפות לשימוש בתנועת החלקה לחיזוי החזרה

כדי להפעיל אנימציות של חיזוי החזרה ב-Android 15 ומטה, צריך להביע הסכמה לשימוש בתנועת החזרה החזויה. כדי להפעיל את ההגדרה, מוסיפים את התג android:enableOnBackInvokedCallback="true" לתג <application> או לתגי <activity> בודדים בקובץ AndroidManifest.xml. מידע נוסף זמין במאמר בנושא הפעלת התכונה 'תנועת חזרה עם חיזוי'.

אחרי שהאפליקציה מטרגטת ל-Android 16 (רמת API‏ 36) ומעלה, התכונה 'חזרה עם אנימציה' מופעלת כברירת מחדל.

שימוש בסיסי

מטמיעים את NavigableListDetailPaneScaffold באופן הבא:

  1. שימוש בכיתה שמייצגת את התוכן שנבחר. משתמשים במחלקה Parcelable כדי לתמוך בשמירה ובשחזור של הפריט שנבחר ברשימה. משתמשים בפלאגין kotlin-parcelize כדי ליצור את הקוד בשבילכם.
  2. יצירת ThreePaneScaffoldNavigator עם rememberListDetailPaneScaffoldNavigator.

אמצעי הניווט הזה משמש למעבר בין הרשימה, הפרטים והחלוניות הנוספות. כשמגדירים סוג כללי, רכיב הניווט עוקב גם אחרי המצב של ה-scaffold (כלומר, איזו MyItem מוצגת). מכיוון שהסוג הזה ניתן להעברה, אפשר לשמור את המצב ולשחזר אותו באמצעות רכיב הניווט כדי לטפל אוטומטית בשינויים בהגדרות.

  1. מעבירים את כלי הניווט אל ה-composable‏ NavigableListDetailPaneScaffold.

  2. שולחים את ההטמעה של חלונית הרשימה אל NavigableListDetailPaneScaffold. משתמשים ב-AnimatedPane כדי להחיל את אנימציות ברירת המחדל של החלונית במהלך הניווט. אחר כך משתמשים ב-ThreePaneScaffoldNavigator כדי לנווט לחלונית הפרטים, ListDetailPaneScaffoldRole.Detail, ולהציג את הפריט שהועבר.

  3. כוללים את ההטמעה של חלונית הפרטים ב-NavigableListDetailPaneScaffold.

בסיום הניווט, currentDestination מכיל את החלונית שאליה האפליקציה ניווטה, כולל התוכן שמוצג בחלונית. המאפיין contentKey הוא מאותו סוג שצוין בקריאה המקורית, כך שאפשר לגשת לכל הנתונים שרוצים להציג.

  1. אופציונלי: משנים את defaultBackBehavior ב-NavigableListDetailPaneScaffold. כברירת מחדל, NavigableListDetailPaneScaffold משתמש ב-PopUntilScaffoldValueChange עבור defaultBackBehavior.

אם האפליקציה שלכם דורשת דפוס שונה של ניווט אחורה, אתם יכולים לשנות את ההתנהגות הזו על ידי ציון אפשרות אחרת של BackNavigationBehavior.

BackNavigationBehavior אפשרויות

בקטע הבא מופיעה דוגמה לאפליקציית אימייל עם רשימת אימיילים בחלונית אחת ותצוגה מפורטת בחלונית השנייה.

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

הנה כמה דוגמאות:

  • חלונות מרובים: אתם צופים באימייל (פריט 1) בחלונית הפרטים. אם לוחצים על אימייל אחר (פריט 2), חלונית הפרטים מתעדכנת, אבל חלוניות הרשימה והפרטים נשארות גלויות. לחיצה על 'חזרה' עשויה לגרום ליציאה מהאפליקציה או מתהליך הניווט הנוכחי.
  • חלון יחיד: אתם צופים בפריט 1, ואז בפריט 2. לחיצה על 'הקודם' תחזיר אתכם ישירות לחלונית של רשימת האימיילים.

משתמשים בזה כשרוצים שהמשתמשים יראו מעברים שונים בפריסה בכל פעולת חזרה.

שינוי ערך הניווט.
PopUntilContentChange

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

הנה כמה דוגמאות:

  • חלונות מרובים: אתם צופים בפריט 1 בחלונית הפרטים, ואז לוחצים על פריט 2 ברשימה. חלונית הפרטים מתעדכנת. לחיצה על 'הקודם' תחזיר את חלונית הפרטים לפריט 1.
  • חלון יחיד: מתרחשת אותה חזרה לגרסה קודמת של התוכן.

משתמשים בזה כשהמשתמש מצפה לחזור לתוכן שנצפה קודם באמצעות פעולת החזרה.

המעבר בין שני חלוניות פרטים
PopUntilCurrentDestinationChange

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

הנה כמה דוגמאות:

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

משתמשים בזה כשחשוב לספק למשתמשים אינדיקציה חזותית ברורה של הניווט הנוכחי.

ניווט בין חלונית הפרטים לחלונית הרשימה
PopLatest

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

אחרי שמבצעים את השלבים האלה, הקוד אמור להיראות בערך כך:

val scaffoldNavigator = rememberListDetailPaneScaffoldNavigator<MyItem>()
val scope = rememberCoroutineScope()

NavigableListDetailPaneScaffold(
    navigator = scaffoldNavigator,
    listPane = {
        AnimatedPane {
            MyList(
                onItemClick = { item ->
                    // Navigate to the detail pane with the passed item
                    scope.launch {
                        scaffoldNavigator.navigateTo(
                            ListDetailPaneScaffoldRole.Detail,
                            item
                        )
                    }
                },
            )
        }
    },
    detailPane = {
        AnimatedPane {
            // Show the detail pane content if selected item is available
            scaffoldNavigator.currentDestination?.contentKey?.let {
                MyDetails(it)
            }
        }
    },
)