สำหรับแอปทีวี ประสบการณ์การเรียกดูจะขึ้นอยู่กับการนำทางที่อิงตามโฟกัสที่มีประสิทธิภาพ การใช้เลย์เอาต์แบบเลื่อนที่ขี้เกียจของ Compose Foundation มาตรฐานจะช่วยให้คุณสร้างรายการแนวตั้งและแนวนอนที่มีประสิทธิภาพ ซึ่งจะจัดการการเลื่อนที่ขับเคลื่อนด้วยโฟกัสโดยอัตโนมัติ เพื่อให้รายการที่ใช้งานอยู่แสดงอยู่
ลักษณะการเลื่อนเริ่มต้นที่ปรับให้เหมาะกับทีวี
ตั้งแต่ Compose Foundation 1.7.0 เป็นต้นไป เลย์เอาต์ Lazy มาตรฐาน (เช่น 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 ที่กำหนดเอง
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) |