สำหรับแอป TV ประสบการณ์การท่องเว็บจะอาศัยการไปยังส่วนต่างๆ ที่อิงตามโฟกัสที่มีประสิทธิภาพ เมื่อใช้เลย์เอาต์แบบ Lazy ของ Compose Foundation มาตรฐาน คุณจะสร้างรายการแนวตั้งและแนวนอนที่มีประสิทธิภาพซึ่งจัดการการเลื่อนที่ขับเคลื่อนด้วยโฟกัสโดยอัตโนมัติเพื่อให้รายการที่ใช้งานอยู่ยังคงปรากฏในมุมมองได้
ลักษณะการเลื่อนเริ่มต้นที่เพิ่มประสิทธิภาพสำหรับทีวี
ตั้งแต่ Compose Foundation 1.7.0 เป็นต้นไป เลย์เอาต์แบบ Lazy มาตรฐาน (เช่น LazyRow และ LazyColumn) จะรองรับฟีเจอร์การจัดตำแหน่งโฟกัสในตัว วิธีนี้เป็นวิธีที่แนะนำในการสร้างแคตตาล็อกสำหรับแอป TV เนื่องจากช่วยให้รายการที่โฟกัสยังคงมองเห็นได้และอยู่ในตำแหน่งที่ผู้ใช้เข้าใจได้ง่าย
หากต้องการใช้รายการที่เลื่อนได้แบบพื้นฐาน ให้ใช้คอมโพเนนต์ 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 เอง
คอมโพสิเบิลตัวช่วยต่อไปนี้ช่วยให้คุณกำหนด "Pivot" ตามเศษส่วนของระดับบนและระดับย่อยได้ 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. เลือกไม่ใช้เลย์เอาต์ที่ฝังไว้บางรายการ
หากคุณมีเลย์เอาต์ที่ฝังเฉพาะซึ่งควรใช้ลักษณะการเลื่อนมาตรฐานแทน Pivot ที่กำหนดเอง ให้ระบุ 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
เลย์เอาต์แบบ Lazy สำหรับทีวีโดยเฉพาะใน androidx.tv.foundation เลิกใช้งานแล้วเพื่อสนับสนุนเลย์เอาต์ Compose Foundation มาตรฐาน
การอัปเดตทรัพยากร Dependency
ตรวจสอบว่า build.gradle ใช้เวอร์ชัน 1.7.0 ขึ้นไปสำหรับรายการต่อไปนี้
androidx.compose.foundationandroidx.compose.runtime
การแมปคอมโพเนนต์
หากต้องการย้ายข้อมูล ให้อัปเดตการนําเข้าและนําคํานําหน้า Tv ออกจากคอมโพเนนต์ ดังนี้
| คอมโพเนนต์ทีวีที่เลิกใช้งานแล้ว | การแทนที่ Compose Foundation |
|---|---|
| TvLazyRow | LazyRow |
| TvLazyColumn | LazyColumn |
| TvLazyHorizontalGrid | LazyHorizontalGrid |
| TvLazyVerticalGrid | LazyVerticalGrid |
| pivotOffsets | BringIntoViewSpec (ผ่าน LocalBringIntoViewSpec) |