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

תבנית 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. מעבירים את ה-Navigator אל ה-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

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

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

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)
            }
        }
    },
)