באפליקציות לטלוויזיה, חוויית הגלישה מבוססת על ניווט יעיל שמבוסס על מיקוד. באמצעות פריסות עצלות של Compose Foundation, אפשר ליצור רשימות אנכיות ואופקיות עם ביצועים טובים, שכוללות גלילה אוטומטית מבוססת-מיקוד כדי להציג את הפריטים הפעילים.
התנהגות ברירת המחדל של הגלילה מותאמת לטלוויזיה
החל מ-Compose Foundation 1.7.0, פריסות סטנדרטיות בטעינה מדורגת (כמו LazyRow
ו-LazyColumn) כוללות תמיכה מובנית בתכונות של מיקום המיקוד. זו הדרך המומלצת ליצור קטלוגים לאפליקציות לטלוויזיה, כי היא עוזרת לשמור על פריטים ממוקדים שיהיו גלויים ולמקם אותם בצורה אינטואיטיבית למשתמש.
כדי להטמיע רשימה בסיסית שאפשר לגלול בה, משתמשים ברכיבי lazy רגילים. הרכיבים האלה מטפלים אוטומטית בניווט באמצעות לחצני החיצים ומציגים את הפריט המודגש.
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 בהתאמה אישית
הפונקציה הבאה שניתנת להרכבה מאפשרת להגדיר 'נקודת ציר' על סמך שברים של הורה וצאצא. המאפיין 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) |