רשימה-פרטים היא תבנית של ממשק משתמש שמורכבת מפריסה של שתי חלוניות, שבאחת מהן מוצגת רשימה של פריטים ובשנייה מוצגים הפרטים של הפריטים שנבחרו מהרשימה.
התבנית הזו שימושית במיוחד לאפליקציות שמספקות מידע מעמיק על רכיבים של אוספים גדולים, למשל, תוכנת אימייל שיש בה רשימה של אימיילים והתוכן המפורט של כל הודעת אימייל. אפשר להשתמש בתצוגת רשימה-פרטים גם לנתיבים פחות קריטיים, כמו חלוקת ההעדפות באפליקציה לרשימה של קטגוריות, כשההעדפות של כל קטגוריה מוצגות בחלונית הפרטים.
הטמעת תבנית הרשימה והפרטים באמצעות NavigableListDetailPaneScaffold
NavigableListDetailPaneScaffold הוא רכיב קומפוזבילי שמפשט את ההטמעה של פריסת רשימה-פרטים ב-Jetpack Compose. הוא כולל את 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'
- adaptive: אבני בניין ברמה נמוכה כמו
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 באופן הבא:
- משתמשים במחלקה שמייצגת את התוכן שנבחר. משתמשים במחלקה
Parcelableכדי לתמוך בשמירה ובשחזור של הפריט שנבחר ברשימה. משתמשים בפלאגין kotlin-parcelize כדי ליצור את הקוד. - יצירת
ThreePaneScaffoldNavigatorעםrememberListDetailPaneScaffoldNavigator.
הניווט הזה משמש למעבר בין הרשימה, הפרטים והחלוניות הנוספות. כשמצהירים על סוג גנרי, ה-navigator גם עוקב אחרי המצב של ה-scaffold (כלומר, איזה MyItem מוצג). מכיוון שהסוג הזה ניתן להעברה, ה-navigator יכול לשמור ולשחזר את המצב כדי לטפל באופן אוטומטי בשינויים בהגדרות האישיות.
מעבירים את ה-navigator לרכיב הקומפוזבילי
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
האפשרות הזו מסירה רק את היעד האחרון מהמחסנית. האפשרות הזו משמשת לניווט לאחור בלי לדלג על מצבי ביניים.
אחרי שתבצעו את השלבים האלה, הקוד אמור להיראות בערך כך:
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 ) } } ) } }