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

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

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

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

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

NavigableListDetailPaneScaffold הוא קומפוזבילי שמפשט את ההטמעה של פריסת רשימה ופרטים ב-Jetpack Compose. הוא עוטף את 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. מעבירים את אובייקט הניווט לרכיב הקומפוזבילי 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 ברשימה. חלונית הפרטים מתעדכנת. לחיצה על 'הקודם' תחזיר את חלונית הפרטים אל Item 1.
  • חלון יחיד: מתרחשת אותה חזרה לגרסה קודמת של התוכן.

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

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

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

מומלץ להביא בחשבון את הדוגמאות הבאות:

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

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

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

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

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

NavigableListDetailPaneScaffold(
    navigator = navigator,
    listPane = {
        AnimatedPane {
            ListContent(
                words = sampleWords,
                selectionState = navigator.currentDestination?.contentKey?.let {
                    SelectionVisibilityState.ShowSelection(it)
                } ?: SelectionVisibilityState.NoSelection,
                onWordClick = { word ->
                    scope.launch {
                        navigator.navigateTo(ListDetailPaneScaffoldRole.Detail, word)
                    }
                },
                animatedVisibilityScope = this@AnimatedPane,
                sharedTransitionScope = this@SharedTransitionLayout
            )
        }
    },
    detailPane = {
        AnimatedPane {
            DetailContent(
                definedWord = navigator.currentDestination?.contentKey,
                animatedVisibilityScope = this@AnimatedPane,
                sharedTransitionScope = this@SharedTransitionLayout,
                onClosePane = {
                    scope.launch {
                        navigator.navigateBack(
                            backNavigationBehavior = BackNavigationBehavior.PopUntilScaffoldValueChange
                        )

                    }
                }
            )
        }
    }