Untuk aplikasi TV, pengalaman penjelajahan mengandalkan navigasi berbasis fokus yang efisien. Dengan menggunakan tata letak lambat Compose Foundation standar, Anda dapat membuat daftar vertikal dan horizontal berperforma tinggi yang otomatis menangani scroll berbasis fokus untuk menjaga item aktif tetap terlihat.
Perilaku scroll default yang dioptimalkan untuk TV
Mulai Compose Foundation 1.7.0, tata letak lazy standar (seperti LazyRow
dan LazyColumn) menyertakan dukungan bawaan untuk fitur pemosisian fokus. Ini
adalah cara yang direkomendasikan untuk membuat katalog untuk aplikasi TV karena membantu menjaga item
yang difokuskan tetap terlihat dan diposisikan secara intuitif bagi pengguna.
Untuk menerapkan daftar dasar yang dapat di-scroll, gunakan komponen lazy standar. Komponen ini otomatis menangani navigasi D-pad dan menampilkan item yang difokuskan.
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 */ } ) } } }
Menyesuaikan perilaku scroll dengan BringIntoViewSpec
Jika desain Anda memerlukan titik "pivot" tertentu (misalnya, menjaga item yang difokuskan tepat 30% dari tepi kiri), Anda dapat menyesuaikan perilaku scroll menggunakan BringIntoViewSpec. Hal ini menggantikan fungsi pivotOffsets
yang lebih lama dengan memungkinkan Anda menentukan dengan tepat cara area pandang harus di-scroll
untuk mengakomodasi item yang difokuskan.
1. Menentukan BringIntoViewSpec kustom
Composable helper berikut memungkinkan Anda menentukan "pivot" berdasarkan pecahan induk dan
turunan. parentFraction menentukan tempat item akan ditempatkan dalam penampung, dan childFraction menentukan bagian item yang sejajar dengan titik tersebut.
@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. Menerapkan spesifikasi kustom
Gabungkan tata letak Anda dengan helper untuk menerapkan pemosisian. Hal ini berguna untuk membuat "garis fokus yang konsisten" di berbagai baris katalog Anda.
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. Memilih tidak ikut tata letak bertingkat tertentu
Jika Anda memiliki tata letak bertingkat tertentu yang harus menggunakan perilaku scroll standar,
bukan pivot kustom, berikan 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 { /* ... */ } } } } }
Akibatnya, meneruskan BringIntoViewSpec kosong akan memungkinkan perilaku default framework mengambil alih.
Migrasi dari TV Foundation ke Compose Foundation
Tata letak lambat khusus TV di androidx.tv.foundation tidak digunakan lagi dan digantikan
oleh tata letak Compose Foundation standar.
Update dependensi
Pastikan build.gradle Anda menggunakan versi 1.7.0 atau yang lebih tinggi untuk:
androidx.compose.foundationandroidx.compose.runtime
Pemetaan komponen
Untuk bermigrasi, update impor Anda dan hapus awalan Tv dari komponen Anda:
| Komponen TV yang tidak digunakan lagi | Penggantian Compose Foundation |
|---|---|
| TvLazyRow | LazyRow |
| TvLazyColumn | LazyColumn |
| TvLazyHorizontalGrid | LazyHorizontalGrid |
| TvLazyVerticalGrid | LazyVerticalGrid |
| pivotOffsets | BringIntoViewSpec (melalui LocalBringIntoViewSpec) |