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


הטמעה של תבנית רשימה עם פרטים באמצעות NavigableListDetailPaneScaffold
NavigableListDetailPaneScaffold
הוא קומפוננטה שאפשר להשתמש בה כדי להטמיע בקלות פריסת רשימה עם פרטים ב-Jetpack פיתוח נייטיב. הוא עוטף את ListDetailPaneScaffold
ומוסיף ניווט מובנה ואנימציות של חיזוי תנועת החזרה.
פיגום של רשימה עם פרטים תומך בעד שלושה חלוניות:
- חלונית הרשימה: מוצג בה אוסף של פריטים.
- חלונית הפרטים: מוצגים בה הפרטים של הפריט שנבחר.
- חלונית נוספת (אופציונלית): מספקת הקשר נוסף כשצריך.
הפיגום מותאם בהתאם לגודל החלון:
- בחלונות גדולים, חלוניות הרשימה והפרטים מופיעות זו לצד זו.
- בחלונות קטנים, רק חלונית אחת גלויה בכל פעם, והיא משתנה כשמשתמשים עוברים בין החלוניות.
הצהרה על יחסי תלות
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
באופן הבא:
- משתמשים במחלקה שמייצגת את התוכן שנבחר. משתמשים במחלקה
Parcelable
כדי לתמוך בשמירה ובשחזור של הפריט שנבחר ברשימה. משתמשים בפלאגין kotlin-parcelize כדי ליצור את הקוד בשבילכם. - יצירת
ThreePaneScaffoldNavigator
עםrememberListDetailPaneScaffoldNavigator
.
אמצעי הניווט הזה משמש למעבר בין הרשימה, הפרטים והחלוניות הנוספות. כשמצהירים על סוג כללי, רכיב הניווט עוקב גם אחרי המצב של ה-scaffold (כלומר, איזו MyItem
מוצגת). מכיוון שהסוג הזה ניתן להעברה, אפשר לשמור את המצב ולשחזר אותו באמצעות רכיב הניווט כדי לטפל אוטומטית בשינויים בהגדרות.
מעבירים את ה-Navigator אל ה-composable
NavigableListDetailPaneScaffold
.שולחים את ההטמעה של חלונית הרשימה אל
NavigableListDetailPaneScaffold
. משתמשים ב-AnimatedPane
כדי להחיל את אנימציות ברירת המחדל של החלונית במהלך הניווט. אחר כך משתמשים ב-ThreePaneScaffoldNavigator
כדי לנווט לחלונית הפרטים,ListDetailPaneScaffoldRole.Detail
, ולהציג את הפריט שהועבר.כוללים את ההטמעה של חלונית הפרטים ב-
NavigableListDetailPaneScaffold
.
בסיום הניווט, currentDestination
מכיל את החלונית שאליה האפליקציה ניווטה, כולל התוכן שמוצג בחלונית. המאפיין contentKey
הוא מאותו סוג שצוין בקריאה המקורית, כך שאפשר לגשת לכל הנתונים שרוצים להציג.
- אופציונלי: משנים את
defaultBackBehavior
ב-NavigableListDetailPaneScaffold
. כברירת מחדל,NavigableListDetailPaneScaffold
משתמש ב-PopUntilScaffoldValueChange
עבורdefaultBackBehavior
.
אם האפליקציה שלכם דורשת דפוס שונה של ניווט אחורה, אתם יכולים לשנות את ההתנהגות הזו על ידי ציון אפשרות אחרת של BackNavigationBehavior
.
BackNavigationBehavior
אפשרויות
בקטע הבא מופיעה דוגמה לאפליקציית אימייל עם רשימת אימיילים בחלונית אחת ותצוגה מפורטת בחלונית השנייה.
PopUntilScaffoldValueChange
(ברירת המחדל ומומלץ ברוב המקרים)
ההתנהגות הזו מתמקדת בשינויים במבנה הפריסה הכולל. בהגדרה של כמה חלוניות, שינוי תוכן האימייל בחלונית הפרטים לא משנה את מבנה הפריסה הבסיסי. לכן, יכול להיות שלחיצה על לחצן 'הקודם' תגרום ליציאה מהאפליקציה או מגרף הניווט הנוכחי, כי אין שינוי בפריסה שאפשר לחזור אליו בהקשר הנוכחי. בפריסה עם חלונית אחת, לחיצה על 'הקודם' תדלג על שינויים בתוכן בתצוגה המפורטת ותחזור לתצוגת הרשימה, כי זה מייצג שינוי ברור בפריסה.
הנה כמה דוגמאות:
- חלונות מרובים: אתם צופים באימייל (פריט 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) } } }, )