Pengubah
verticalScroll
dan
horizontalScroll
memberikan cara termudah untuk memungkinkan pengguna men-scroll elemen jika
batas kontennya lebih besar dari batasan ukuran maksimumnya. Dengan pengubah verticalScroll dan horizontalScroll, Anda tidak perlu menerjemahkan atau melakukan offset pada konten tersebut.
@Composable private fun ScrollBoxes() { Column( modifier = Modifier .background(Color.LightGray) .size(100.dp) .verticalScroll(rememberScrollState()) ) { repeat(10) { Text("Item $it", modifier = Modifier.padding(2.dp)) } } }
The ScrollState
memungkinkan Anda mengubah posisi scroll atau mendapatkan status saat ini. Untuk membuatnya
dengan parameter default, gunakan
rememberScrollState().
@Composable private fun ScrollBoxesSmooth() { // Smoothly scroll 100px on first composition val state = rememberScrollState() LaunchedEffect(Unit) { state.animateScrollTo(100) } Column( modifier = Modifier .background(Color.LightGray) .size(100.dp) .padding(horizontal = 8.dp) .verticalScroll(state) ) { repeat(10) { Text("Item $it", modifier = Modifier.padding(2.dp)) } } }
Pengubah area yang dapat di-scroll
Pengubah scrollableArea adalah elemen penyusun dasar untuk membuat
penampung yang dapat di-scroll kustom. Pengubah ini menyediakan abstraksi tingkat yang lebih tinggi atas pengubah
scrollable, yang menangani persyaratan umum seperti interpretasi delta gestur, kliping konten, dan efek overscroll.
Meskipun scrollableArea digunakan untuk penerapan kustom, Anda umumnya
harus memilih solusi siap pakai seperti verticalScroll, horizontalScroll,
atau composable seperti LazyColumn untuk daftar scroll standar. Komponen tingkat yang lebih tinggi ini lebih sederhana untuk kasus penggunaan umum dan dibuat menggunakan scrollableArea.
Perbedaan antara scrollableArea dan scrollable pengubah
Perbedaan utama antara scrollableArea dan scrollable terletak pada cara keduanya
menafsirkan gestur scroll pengguna:
scrollable(delta mentah): Delta secara langsung mencerminkan gerakan fisik input pengguna (misalnya, pointer drag) di layar.scrollableArea(delta berorientasi konten):deltasecara semantik dibalik untuk mewakili perubahan yang dipilih dalam posisi scroll agar konten tampak bergerak dengan gestur pengguna, yang biasanya berlawanan dengan gerakan pointer.
Bayangkan seperti ini: scrollable memberi tahu Anda cara pointer bergerak, sedangkan
scrollableArea menerjemahkan gerakan pointer tersebut ke dalam cara konten harus
bergerak dalam tampilan yang dapat di-scroll. Inversi ini membuat scrollableArea terasa lebih alami saat menerapkan penampung yang dapat di-scroll standar.
Tabel berikut merangkum tanda delta untuk skenario umum:
Gestur pengguna |
delta yang dilaporkan ke |
delta yang dilaporkan ke |
|---|---|---|
Pointer bergerak KE ATAS |
Negatif |
Positif |
Pointer bergerak KE BAWAH |
Positif |
Negatif |
Pointer bergerak KE KIRI |
Negatif |
Positif (Negatif untuk RTL) |
Pointer bergerak KE KANAN |
Positif |
Negatif (Positif untuk RTL) |
(*) Catatan tentang tanda delta scrollableArea: Tanda delta dari
scrollableArea bukan hanya inversi sederhana. Tanda ini mempertimbangkan secara cerdas:
- Orientasi: Vertikal atau horizontal.
LayoutDirection: LTR atau RTL (terutama penting untuk scroll horizontal).- Flag
reverseScrolling: Apakah arah scroll dibalik.
Selain membalikkan delta scroll, scrollableArea juga memangkas konten ke batas tata letak dan menangani rendering efek overscroll. Secara default, efek yang disediakan oleh LocalOverscrollFactory akan digunakan.
Anda dapat menyesuaikan atau menonaktifkannya menggunakan scrollableArea overload
yang menerima parameter OverscrollEffect.
Kapan harus menggunakan pengubah scrollableArea
Anda harus menggunakan pengubah scrollableArea saat perlu membuat komponen scroll kustom yang tidak dilayani secara memadai oleh pengubah horizontalScroll atau verticalScroll atau tata letak Lazy. Hal ini sering kali melibatkan kasus dengan:
- Logika tata letak kustom: Saat pengaturan item berubah secara dinamis berdasarkan posisi scroll.
- Efek visual unik: Menerapkan transformasi, penskalaan, atau efek lainnya ke turunan saat di-scroll.
- Kontrol langsung: Memerlukan kontrol terperinci atas mekanisme scroll
di luar yang diekspos oleh
verticalScrollatau tata letak Lazy.
Membuat daftar kustom seperti roda menggunakan scrollableArea
Contoh berikut menunjukkan penggunaan scrollableArea untuk membuat daftar vertikal kustom tempat item diperkecil saat bergerak menjauh dari tengah, sehingga membuat efek visual "seperti roda". Jenis transformasi yang bergantung pada scroll ini adalah kasus penggunaan yang sempurna untuk scrollableArea.
scrollableArea.
@Composable private fun ScrollableAreaSample() { // ... Layout( modifier = Modifier .size(150.dp) .scrollableArea(scrollState, Orientation.Vertical) .background(Color.LightGray), // ... ) { measurables, constraints -> // ... // Update the maximum scroll value to not scroll beyond limits and stop when scroll // reaches the end. scrollState.maxValue = (totalHeight - viewportHeight).coerceAtLeast(0) // Position the children within the layout. layout(constraints.maxWidth, viewportHeight) { // The current vertical scroll position, in pixels. val scrollY = scrollState.value val viewportCenterY = scrollY + viewportHeight / 2 var placeableLayoutPositionY = 0 placeables.forEach { placeable -> // This sample applies a scaling effect to items based on their distance // from the center, creating a wheel-like effect. // ... // Place the item horizontally centered with a layer transformation for // scaling to achieve wheel-like effect. placeable.placeRelativeWithLayer( x = constraints.maxWidth / 2 - placeable.width / 2, // Offset y by the scroll position to make placeable visible in the viewport. y = placeableLayoutPositionY - scrollY, ) { scaleX = scaleFactor scaleY = scaleFactor } // Move to the next item's vertical position. placeableLayoutPositionY += placeable.height } } } } // ...
Pengubah yang dapat di-scroll
Pengubah
scrollable
berbeda dengan pengubah scroll dalam scrollable yang mendeteksi
gestur scroll dan mengambil delta, tetapi tidak mengimbangi kontennya
secara otomatis. Hal ini didelegasikan kepada pengguna melalui
ScrollableState
, yang diperlukan agar pengubah ini berfungsi dengan benar.
Saat membuat ScrollableState, Anda harus menyediakan fungsi consumeScrollDelta yang akan dipanggil pada setiap langkah scroll (dengan input gestur, scroll halus, atau lempar) dengan delta dalam piksel. Fungsi ini harus menampilkan jumlah jarak scroll yang digunakan untuk memastikan peristiwa disebarkan dengan benar jika ada elemen bertingkat yang memiliki pengubah scrollable.
Cuplikan berikut mendeteksi gestur dan menampilkan nilai numerik untuk offset, tetapi tidak melakukan offset pada elemen apa pun:
@Composable private fun ScrollableSample() { // actual composable state var offset by remember { mutableFloatStateOf(0f) } Box( Modifier .size(150.dp) .scrollable( orientation = Orientation.Vertical, // Scrollable state: describes how to consume // scrolling delta and update offset state = rememberScrollableState { delta -> offset += delta delta } ) .background(Color.LightGray), contentAlignment = Alignment.Center ) { Text(offset.toString()) } }
Direkomendasikan untuk Anda
- Catatan: teks link ditampilkan saat JavaScript nonaktif
- Memahami gestur
- Memigrasikan
CoordinatorLayoutke Compose - Menggunakan View di Compose