הפריסה של חלונית התמיכה מאפשרת למשתמש להתמקד בתוכן הראשי של האפליקציה, תוך הצגת מידע תומך רלוונטי. לדוגמה, בחלונית הראשית יכולים להופיע פרטים על סרט, ובחלונית התומכת יכולים להופיע סרטים דומים, סרטים של אותו במאי או יצירות שבהן מופיעים אותם שחקנים.
פרטים נוספים זמינים בהנחיות לגבי חלונית התמיכה של חומר 3.
הטמעת חלונית תמיכה באמצעות NavigableSupportingPaneScaffold
NavigableSupportingPaneScaffold
הוא רכיב שקל להטמיע באמצעותו פריסה של חלונית תמיכה ב-Jetpack Compose. הוא עוטף את SupportingPaneScaffold
ומוסיף ניווט מובנה וטיפול חזוי בלחצן 'הקודם'.
תומך של חלונית תומכת יכול לתמוך בעד שלוש חלוניות:
- החלונית הראשית: כאן מוצג התוכן הראשי.
- חלונית תמיכה: מספקת הקשר או כלים נוספים שקשורים לחלונית הראשית.
- חלונית נוספת (אופציונלי): משמשת לתוכן משלים במקרה הצורך.
התבנית מתאימה את עצמה בהתאם לגודל החלון:
- בחלונות גדולים, החלונית הראשית והחלונית התומכת מופיעות זו לצד זו.
בחלונות קטנים, רק חלונית אחת מוצגת בכל פעם, והיא משתנה בהתאם לניווט של המשתמשים.
איור 1. תמיכה בפריסה של חלוניות.
הוספת יחסי תלות
NavigableSupportingPaneScaffold
הוא חלק מספריית הפריסות המותאמות של 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>
[או את הערך android:enableOnBackInvokedCallback="true"
לתג <application>
או לתגים <activity>
הנפרדים] בקובץ AndroidManifest.xml
.
אחרי שהאפליקציה שלכם מטרגטת ל-Android 16 (רמת API 36) ואילך, האפשרות 'חזרה חזותית חזרה' מופעלת כברירת מחדל.
יצירת ניווט
בחלונות קטנים מוצגת רק חלונית אחת בכל פעם, לכן צריך להשתמש בThreePaneScaffoldNavigator
כדי לעבור בין החלונות. יוצרים מכונה של הניווט באמצעות rememberSupportingPaneScaffoldNavigator
.
val scaffoldNavigator = rememberSupportingPaneScaffoldNavigator() val scope = rememberCoroutineScope()
העברת הניווט למבנה העזר
למבנה העזר נדרש ThreePaneScaffoldNavigator
, שהוא ממשק שמייצג את המצב של המבנה, את ThreePaneScaffoldValue
ואת PaneScaffoldDirective
.
NavigableSupportingPaneScaffold( navigator = scaffoldNavigator, mainPane = { /*...*/ }, supportingPane = { /*...*/ }, )
החלונית הראשית והחלונית התומכת הן רכיבים שאפשר לשלב ביניהם, שמכילים את התוכן שלכם. כדי להחיל את אנימציות ברירת המחדל של החלוניות במהלך הניווט, משתמשים ב-AnimatedPane
. משתמשים בערך של התבנית כדי לבדוק אם חלונית התמיכה מוסתרת. אם כן, מציגים לחצן שמפעיל את navigateTo(SupportingPaneScaffoldRole.Supporting)
כדי להציג את חלונית התמיכה.
זוהי הטמעה מלאה של התבנית:
val scaffoldNavigator = rememberSupportingPaneScaffoldNavigator() val scope = rememberCoroutineScope() NavigableSupportingPaneScaffold( navigator = scaffoldNavigator, mainPane = { AnimatedPane( modifier = Modifier .safeContentPadding() .background(Color.Red) ) { if (scaffoldNavigator.scaffoldValue[SupportingPaneScaffoldRole.Supporting] == PaneAdaptedValue.Hidden) { Button( modifier = Modifier .wrapContentSize(), onClick = { scope.launch { scaffoldNavigator.navigateTo(SupportingPaneScaffoldRole.Supporting) } } ) { Text("Show supporting pane") } } else { Text("Supporting pane is shown") } } }, supportingPane = { AnimatedPane(modifier = Modifier.safeContentPadding()) { Text("Supporting pane") } } )
חילוץ רכיבים שניתנים לקישור בחלונית
כדאי לחלץ את החלונות הנפרדים של SupportingPaneScaffold
לרכיבים משלהם כדי שאפשר יהיה להשתמש בהם שוב ולבדוק אותם. משתמשים ב-ThreePaneScaffoldScope
כדי לגשת ל-AnimatedPane
אם רוצים להשתמש באנימציות ברירת המחדל:
@OptIn(ExperimentalMaterial3AdaptiveApi::class) @Composable fun ThreePaneScaffoldPaneScope.MainPane( shouldShowSupportingPaneButton: Boolean, onNavigateToSupportingPane: () -> Unit, modifier: Modifier = Modifier, ) { AnimatedPane( modifier = modifier.safeContentPadding() ) { // Main pane content if (shouldShowSupportingPaneButton) { Button(onClick = onNavigateToSupportingPane) { Text("Show supporting pane") } } else { Text("Supporting pane is shown") } } } @OptIn(ExperimentalMaterial3AdaptiveApi::class) @Composable fun ThreePaneScaffoldPaneScope.SupportingPane( modifier: Modifier = Modifier, ) { AnimatedPane(modifier = modifier.safeContentPadding()) { // Supporting pane content Text("This is the supporting pane") } }
חילוץ החלונות לרכיבים מורכבים מפשט את השימוש ב-SupportingPaneScaffold
(אפשר להשוות את הקוד הבא להטמעה המלאה של התשתית בקטע הקודם):
val scaffoldNavigator = rememberSupportingPaneScaffoldNavigator() val scope = rememberCoroutineScope() NavigableSupportingPaneScaffold( navigator = scaffoldNavigator, mainPane = { MainPane( shouldShowSupportingPaneButton = scaffoldNavigator.scaffoldValue.secondary == PaneAdaptedValue.Hidden, onNavigateToSupportingPane = { scope.launch { scaffoldNavigator.navigateTo(ThreePaneScaffoldRole.Secondary) } } ) }, supportingPane = { SupportingPane() }, )
אם אתם רוצים יותר שליטה על היבטים ספציפיים של התבנית, כדאי להשתמש ב-SupportingPaneScaffold
במקום ב-NavigableSupportingPaneScaffold
. אפשר להזין את הערכים PaneScaffoldDirective
ו-ThreePaneScaffoldValue
או את הערכים ThreePaneScaffoldState
בנפרד. הגמישות הזו מאפשרת לכם להטמיע לוגיקה מותאמת אישית למרווח בין החלונות ולקבוע כמה חלונות יוצגו בו-זמנית. אפשר גם להוסיף את הערך ThreePaneScaffoldPredictiveBackHandler
כדי להפעיל תמיכה בחזור חזרה אוטומטי.
הוספה של ThreePaneScaffoldPredictiveBackHandler
מחברים את ה-handler לחיזוי תנועת החזרה, שמקבל מכונה של ניווט בסכימה ומציינים את backBehavior
. ההגדרה הזו קובעת איך יעברו יעדים מהמקבץ הקודם בזמן ניווט לאחור. לאחר מכן מעבירים את scaffoldDirective
ו-scaffoldState
אל SupportingPaneScaffold
. משתמשים בעלות יתר שמקבלת ThreePaneScaffoldState
ומעבירים את הערך scaffoldNavigator.scaffoldState
.
מגדירים את החלוניות הראשית והתומכת ב-SupportingPaneScaffold
. משתמשים ב-AnimatedPane
כדי להפעיל אנימציות ברירת מחדל של חלוניות.
אחרי שתטמיעו את השלבים האלה, הקוד שלכם אמור להיראות כך:
val scaffoldNavigator = rememberSupportingPaneScaffoldNavigator() val scope = rememberCoroutineScope() ThreePaneScaffoldPredictiveBackHandler( navigator = scaffoldNavigator, backBehavior = BackNavigationBehavior.PopUntilScaffoldValueChange ) SupportingPaneScaffold( directive = scaffoldNavigator.scaffoldDirective, scaffoldState = scaffoldNavigator.scaffoldState, mainPane = { MainPane( shouldShowSupportingPaneButton = scaffoldNavigator.scaffoldValue.secondary == PaneAdaptedValue.Hidden, onNavigateToSupportingPane = { scope.launch { scaffoldNavigator.navigateTo(ThreePaneScaffoldRole.Secondary) } } ) }, supportingPane = { SupportingPane() }, )