टीवी ऐप्लिकेशन के लिए, ब्राउज़िंग का अनुभव, फ़ोकस-आधारित नेविगेशन पर निर्भर करता है. 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 (via LocalBringIntoViewSpec) |