Pengubah scroll
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)) } } }
Dengan ScrollState, Anda dapat 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 memberikan abstraksi tingkat yang lebih tinggi atas pengubah
scrollable, yang menangani persyaratan umum seperti interpretasi delta gestur, pemangkasan konten, dan efek overscroll.
Meskipun scrollableArea digunakan untuk penerapan kustom, Anda umumnya harus
lebih 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 dibangun sendiri menggunakan scrollableArea.
Perbedaan antara pengubah scrollableArea dan scrollable
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, penarikan pointer) di layar.scrollableArea(delta berorientasi konten):deltasecara semantik dibalik untuk merepresentasikan perubahan yang dipilih dalam posisi scroll agar konten tampak bergerak dengan gestur pengguna, yang biasanya berlawanan dengan gerakan pointer.
Anggap saja seperti ini: scrollable memberi tahu Anda cara kursor bergerak, sementara
scrollableArea menerjemahkan gerakan kursor tersebut ke cara konten harus
bergerak dalam tampilan yang dapat di-scroll secara umum. Inversi ini adalah alasan mengapa scrollableArea
terasa lebih alami saat menerapkan penampung yang dapat di-scroll standar.
Tabel berikut merangkum tanda delta untuk skenario umum:
Gestur pengguna |
perubahan dilaporkan ke |
delta yang dilaporkan ke |
|---|---|---|
Pointer bergerak UP |
Negatif |
Positif |
Pointer bergerak DOWN |
Positif |
Negatif |
Pointer bergerak ke KIRI |
Negatif |
Positif (Negatif untuk RTL) |
Kursor bergerak ke KANAN |
Positif |
Negatif (Positif untuk RTL) |
(*) Catatan tentang tanda delta scrollableArea: Tanda delta dari
scrollableArea bukan hanya inversi sederhana. Secara cerdas, fitur ini mempertimbangkan:
- Orientasi: Vertikal atau horizontal.
LayoutDirection: LTR atau RTL (terutama penting untuk scrolling horizontal).- Flag
reverseScrolling: Apakah arah scroll dibalik.
Selain membalikkan delta scroll, scrollableArea juga memangkas
konten ke batas tata letak dan menangani rendering efek
scroll berlebih. Secara default, efek yang digunakan adalah efek yang disediakan oleh LocalOverscrollFactory.
Anda dapat menyesuaikan atau menonaktifkannya menggunakan penggantian scrollableArea
yang menerima parameter OverscrollEffect.
Kapan harus menggunakan pengubah scrollableArea
Anda harus menggunakan pengubah scrollableArea saat perlu membuat komponen
scrolling kustom yang tidak cukup dilayani oleh pengubah horizontalScroll atau
verticalScroll atau tata letak Lazy. Hal ini sering kali melibatkan kasus dengan:
- Logika tata letak kustom: Saat susunan item berubah secara dinamis berdasarkan posisi scroll.
- Efek visual yang unik: Menerapkan transformasi, penskalaan, atau efek lain pada anak-anak saat mereka men-scroll.
- Kontrol langsung: Memerlukan kontrol terperinci atas mekanisme scrolling 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 dengan item yang diperkecil saat bergerak menjauh dari tengah, sehingga menciptakan efek visual "seperti roda". Transformasi yang bergantung pada scroll semacam 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 karena scrollable mendeteksi gestur scroll dan mengambil delta, tetapi tidak mengimbangi kontennya secara otomatis. Sebagai gantinya, 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