टीवी ऐप्लिकेशन के लिए, ब्राउज़ करने का अनुभव, फ़ोकस पर आधारित नेविगेशन पर निर्भर करता है. Compose Foundation के स्टैंडर्ड लेज़ी लेआउट का इस्तेमाल करके, वर्टिकल और हॉरिज़ॉन्टल सूचियां बनाई जा सकती हैं. ये सूचियां, फ़ोकस के हिसाब से अपने-आप स्क्रोल होती हैं. इससे, ऐक्टिव आइटम हमेशा दिखते रहते हैं.
टीवी के लिए ऑप्टिमाइज़ किया गया, डिफ़ॉल्ट स्क्रोलिंग का तरीका
Compose Foundation 1.7.0 से, स्टैंडर्ड लेज़ी लेआउट (जैसे, LazyRow और LazyColumn) में, फ़ोकस-पोज़िशनिंग की सुविधाओं के लिए, पहले से मौजूद सहायता शामिल है. टीवी ऐप्लिकेशन के लिए कैटलॉग बनाने का यह सुझाव दिया जाता है. इससे, फ़ोकस किए गए आइटम दिखते रहते हैं और उपयोगकर्ता के लिए, वे आसानी से समझ में आने वाली पोज़िशन में दिखते हैं.
स्क्रोल की जा सकने वाली सामान्य सूची लागू करने के लिए, स्टैंडर्ड लेज़ी कॉम्पोनेंट का इस्तेमाल करें. ये कॉम्पोनेंट, डी-पैड नेविगेशन को अपने-आप हैंडल करते हैं और फ़ोकस किए गए आइटम को दिखाते हैं.
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 के ज़रिए) |