באפליקציות לטלוויזיה, חוויית הגלישה מתבססת על ניווט יעיל שמבוסס על מיקוד. באמצעות פריסות עצלות של Compose Foundation, אפשר ליצור רשימות אנכיות ואופקיות עם ביצועים טובים, שכוללות גלילה אוטומטית שמבוססת על מיקוד כדי להציג את הפריטים הפעילים.
התנהגות ברירת המחדל של הגלילה מותאמת לטלוויזיה
החל מ-Compose Foundation 1.7.0, פריסות רגילות של lazy (כמו LazyRow
ו-LazyColumn) כוללות תמיכה מובנית בתכונות של מיקום המיקוד. זו הדרך המומלצת ליצור קטלוגים לאפליקציות לטלוויזיה, כי היא עוזרת לשמור על פריטים ממוקדים שיהיו גלויים ולמקם אותם בצורה אינטואיטיבית למשתמש.
כדי להטמיע רשימה בסיסית שאפשר לגלול בה, משתמשים ברכיבי lazy רגילים. הרכיבים האלה מטפלים אוטומטית בניווט באמצעות כפתורי החיצים (D-pad) ומציגים את הפריט הממוקד.
import androidx.compose.foundation.lazy.LazyRow import androidx.compose.foundation.lazy.items @Composable fun MovieCatalog(movies: List<Movie>) { LazyRow { items(movies) { movie -> MovieCard( movie = movie, onClick = { /* Handle click */ } ) } } }
התאמה אישית של התנהגות הגלילה באמצעות BringIntoViewSpec
אם העיצוב שלכם דורש נקודת 'ציר' ספציפית (לדוגמה, שמירת הפריט הממוקד בדיוק 30% מהקצה השמאלי), אתם יכולים להתאים אישית את התנהגות הגלילה באמצעות BringIntoViewSpec. הפונקציה הזו מחליפה את הפונקציונליות הישנה יותר של pivotOffsets
ומאפשרת לכם להגדיר בדיוק איך אזור התצוגה צריך לגלול כדי להכיל פריט ממוקד.
1. הגדרה של BringIntoViewSpec בהתאמה אישית
רכיב ה-Composable הבא עוזר להגדיר 'ציר' על סמך שברים של הורה וצאצא. המאפיין parentFraction קובע איפה בקונטיינר הפריט צריך להיות, והמאפיין childFraction קובע איזה חלק של הפריט יתיישר עם הנקודה הזו.
@OptIn(ExperimentalFoundationApi::class) @Composable fun PositionFocusedItemInLazyLayout( parentFraction: Float = 0.3f, childFraction: Float = 0f, content: @Composable () -> Unit, ) { val bringIntoViewSpec = remember(parentFraction, childFraction) { object : BringIntoViewSpec { override fun calculateScrollDistance( offset: Float, // Item's initial position size: Float, // Item's size containerSize: Float // Container's size ): Float { // Calculate the offset position of the item's leading edge. val initialTargetForLeadingEdge = parentFraction * containerSize - (childFraction * size) // If the item fits in the container, and scrolling would cause // its trailing edge to be clipped, adjust targetForLeadingEdge // to prevent over-scrolling near the end of list. val targetForLeadingEdge = if (size <= containerSize && (containerSize - initialTargetForLeadingEdge) < size) { // If clipped, align the item's trailing edge with the // container's trailing edge. containerSize - size } else { initialTargetForLeadingEdge } // Return scroll distance relative to initial item position. return offset - targetForLeadingEdge } } } // Apply the spec to all scrollables in the hierarchy CompositionLocalProvider( LocalBringIntoViewSpec provides bringIntoViewSpec, content = content, ) }
2. החלת המפרט בהתאמה אישית
כדי להחיל את המיקום, עוטפים את הפריסות בעזרת רכיב העזר. האפשרות הזו שימושית ליצירת "קו מיקוד עקבי" בשורות שונות בקטלוג.
PositionFocusedItemInLazyLayout( parentFraction = 0.3f, // Pivot 30% from the edge childFraction = 0.5f // Center of the item aligns with the pivot ) { LazyColumn { items(sectionList) { section -> // This row and its items will respect the 30% pivot LazyRow { /* ... */ } } } }
3. ביטול ההסכמה לפריסות מוטמעות ספציפיות
אם יש לכם פריסה ספציפית עם רכיבים מוטמעים שצריכה להשתמש בהתנהגות גלילה רגילה במקום בשינוי הכיוון המותאם אישית, צריך לספק את DefaultBringIntoViewSpec:
private val DefaultBringIntoViewSpec = object : BringIntoViewSpec {} PositionFocusedItemInLazyLayout { LazyColumn { item { // This row will ignore the custom pivot and use default behavior CompositionLocalProvider(LocalBringIntoViewSpec provides DefaultBringIntoViewSpec) { LazyRow { /* ... */ } } } } }
בפועל, העברת BringIntoViewSpec ריק מאפשרת להתנהגות ברירת המחדל של המסגרת להשתלט.
העברה מ-TV Foundation ל-Compose Foundation
הפריסות העצלניות שספציפיות לטלוויזיה ב-androidx.tv.foundation הוצאו משימוש, ועכשיו משתמשים בפריסות הרגילות של Compose Foundation.
עדכונים של פניות קשורות
מוודאים ש-build.gradle משתמש בגרסה 1.7.0 ואילך עבור:
androidx.compose.foundationandroidx.compose.runtime
מיפוי רכיבים
כדי לבצע את ההעברה, צריך לעדכן את הייבוא ולהסיר את הקידומת Tv מהרכיבים:
| רכיב טלוויזיה שיצא משימוש | החלפה של Compose Foundation |
|---|---|
| TvLazyRow | LazyRow |
| TvLazyColumn | LazyColumn |
| TvLazyHorizontalGrid | LazyHorizontalGrid |
| TvLazyVerticalGrid | LazyVerticalGrid |
| pivotOffsets | BringIntoViewSpec (באמצעות LocalBringIntoViewSpec) |