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

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

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

הטמעה של דפוס ממשק משתמש עם ListDetailPaneScaffold

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

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

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

ListDetailPaneScaffold הוא חלק מספריית הפריסות המותאמות של 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 – רכיבים מורכבים לניווט בתוך חלוניות וביניהן

שימוש בסיסי

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

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

    @Parcelize
    class MyItem(val id: Int) : Parcelable

  2. יוצרים ThreePaneScaffoldNavigator באמצעות rememberListDetailPaneScaffoldNavigator ומוסיפים BackHandler. בעזרת הניווט הזה אפשר לעבור בין הרשימה, חלונית הפרטים והחלוניות הנוספות. כאשר מגדירים סוג כללי, הניווט עוקב גם אחרי מצב התשתית (כלומר, איזה MyItem מוצג). מאחר שסוג זה parcelable, הניווט יכול לשמור ולשחזר את המצב כדי יטפלו אוטומטית בשינויי הגדרות אישיות. BackHandler מספק תמיכה בניווט חזרה באמצעות תנועת החזרה של המערכת, או לחצן. ההתנהגות הצפויה של לחצן 'הקודם' עבור הערך ListDetailPaneScaffold תלוי בגודל החלון וברמה הנוכחית עם ערך מסוים. אם ListDetailPaneScaffold יכול לתמוך בחזרה עם המצב הנוכחי, canNavigateBack() הוא true, מה שמאפשר BackHandler

    val navigator = rememberListDetailPaneScaffoldNavigator<MyItem>()
    
    BackHandler(navigator.canNavigateBack()) {
        navigator.navigateBack()
    }

  3. מעבירים את scaffoldState מ-navigator ל-ListDetailPaneScaffold הניתן ליצירה.

    ListDetailPaneScaffold(
        directive = navigator.scaffoldDirective,
        value = navigator.scaffoldValue,
        // ...
    )

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

    ListDetailPaneScaffold(
        directive = navigator.scaffoldDirective,
        value = navigator.scaffoldValue,
        listPane = {
            AnimatedPane {
                MyList(
                    onItemClick = { item ->
                        // Navigate to the detail pane with the passed item
                        navigator.navigateTo(ListDetailPaneScaffoldRole.Detail, item)
                    }
                )
            }
        },
        // ...
    )

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

    ListDetailPaneScaffold(
        directive = navigator.scaffoldDirective,
        value = navigator.scaffoldValue,
        listPane =
        // ...
        detailPane = {
            AnimatedPane {
                navigator.currentDestination?.content?.let {
                    MyDetails(it)
                }
            }
        },
    )

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

val navigator = rememberListDetailPaneScaffoldNavigator<MyItem>()

BackHandler(navigator.canNavigateBack()) {
    navigator.navigateBack()
}

ListDetailPaneScaffold(
    directive = navigator.scaffoldDirective,
    value = navigator.scaffoldValue,
    listPane = {
        AnimatedPane {
            MyList(
                onItemClick = { item ->
                    // Navigate to the detail pane with the passed item
                    navigator.navigateTo(ListDetailPaneScaffoldRole.Detail, item)
                },
            )
        }
    },
    detailPane = {
        AnimatedPane {
            // Show the detail pane content if selected item is available
            navigator.currentDestination?.content?.let {
                MyDetails(it)
            }
        }
    },
)