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

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

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

חלונית פרטים שמוצגת לצד דף הרשימה.
איור 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")

Groovy

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: רכיבים מורכבים לניווט בתוך חלוניות ובין חלוניות, וכן פריסות מותאמות שמאפשרות ניווט כברירת מחדל, כמו 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.

בעזרת הניווט הזה אפשר לעבור בין הרשימה, הדף המפורט והחלוניות הנוספות. ההצהרה על סוג כללי מאפשרת לנווט גם אחרי מצב התבנית (כלומר, איזה 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.
  • חלון יחיד: מתרחשת אותה חזרה לאחור של התוכן.

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

המעבר בין שתי חלוניות מפורטות
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)
            }
        }
    },
)