ตัวแก้ไข
verticalScroll
และ
horizontalScroll
เป็นวิธีที่ง่ายที่สุดในการอนุญาตให้ผู้ใช้เลื่อนองค์ประกอบเมื่อ
ขอบเขตของเนื้อหามีขนาดใหญ่กว่าข้อจำกัดด้านขนาดสูงสุด ตัวแก้ไข verticalScroll และ horizontalScroll ไม่จำเป็นต้องแปลหรือชดเชยเนื้อหา
@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)) } } }
ScrollState ช่วยให้คุณเปลี่ยนตำแหน่งการเลื่อนหรือรับสถานะปัจจุบันได้ หากต้องการสร้างด้วยพารามิเตอร์เริ่มต้น ให้ใช้
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)) } } }
ตัวแก้ไขพื้นที่เลื่อนได้
ตัวปรับแต่ง scrollableArea เป็นองค์ประกอบที่ใช้สร้างสรรค์พื้นฐานสำหรับการสร้างคอนเทนเนอร์ที่เลื่อนได้ซึ่งกำหนดเอง โดยจะมีการแยกย่อยระดับสูงกว่าตัวปรับแต่ง
scrollable ซึ่งจัดการข้อกำหนดทั่วไป เช่น การตีความเดลต้าของท่าทางสัมผัส
การตัดเนื้อหา และเอฟเฟกต์การเลื่อนเกิน
แม้ว่าจะใช้ scrollableArea สำหรับการใช้งานที่กำหนดเอง แต่โดยทั่วไปแล้วคุณควรเลือกใช้โซลูชันสำเร็จรูป เช่น verticalScroll, horizontalScroll, หรือคอมโพสได้ เช่น LazyColumn สำหรับรายการการเลื่อนมาตรฐาน คอมโพเนนต์ระดับสูงเหล่านี้ใช้งานง่ายกว่าสำหรับกรณีการใช้งานทั่วไป และสร้างขึ้นโดยใช้ scrollableArea
ความแตกต่างระหว่างตัวแก้ไข scrollableArea และ scrollable
ความแตกต่างหลักระหว่าง scrollableArea และ scrollable อยู่ที่วิธีที่
ตีความท่าทางสัมผัสเพื่อเลื่อนของผู้ใช้ ดังนี้
scrollable(เดลต้าดิบ): เดลต้าจะแสดงการเคลื่อนไหวทางกายภาพของอินพุตของผู้ใช้ (เช่น การลากตัวชี้) บนหน้าจอโดยตรงscrollableArea(เดลต้าที่เน้นเนื้อหา): ระบบจะกลับความหมายของdeltaเพื่อแสดงการเปลี่ยนแปลงที่เลือกในตำแหน่งการเลื่อนเพื่อให้ เนื้อหา ปรากฏขึ้นเพื่อเคลื่อนไหวตามท่าทางสัมผัสของผู้ใช้ ซึ่งโดยปกติแล้วจะตรงข้ามกับการเคลื่อนไหวของตัวชี้
ลองนึกภาพว่า scrollable จะบอกคุณว่าตัวชี้เคลื่อนไหวอย่างไร ขณะที่
scrollableArea จะแปลการเคลื่อนไหวของตัวชี้นั้นเป็นวิธีที่ เนื้อหา ควร
เคลื่อนไหวภายในมุมมองที่เลื่อนได้ทั่วไป การกลับความหมายนี้เองที่ทำให้ scrollableArea ดูเป็นธรรมชาติมากขึ้นเมื่อใช้คอนเทนเนอร์ที่เลื่อนได้มาตรฐาน
ตารางต่อไปนี้สรุปเครื่องหมายเดลต้าสำหรับสถานการณ์ที่พบบ่อย
ท่าทางสัมผัสของผู้ใช้ |
เดลต้าที่รายงานไปยัง |
เดลต้าที่รายงานไปยัง |
|---|---|---|
ตัวชี้เคลื่อนที่ขึ้น |
ค่าลบ |
ค่าบวก |
ตัวชี้เคลื่อนที่ลง |
ค่าบวก |
ค่าลบ |
ตัวชี้เคลื่อนที่ไปทางซ้าย |
ค่าลบ |
ค่าบวก (ค่าลบ สำหรับ RTL) |
ตัวชี้เคลื่อนที่ไปทางขวา |
ค่าบวก |
ค่าลบ (ค่าบวก สำหรับ RTL) |
(*) หมายเหตุเกี่ยวกับเครื่องหมายเดลต้าของ scrollableArea: เครื่องหมายเดลต้าจาก
scrollableArea ไม่ใช่แค่การกลับความหมายแบบง่ายๆ แต่จะพิจารณาอย่างชาญฉลาดในเรื่องต่อไปนี้
- การวางแนว: แนวตั้งหรือแนวนอน
LayoutDirection: LTR หรือ RTL (สำคัญอย่างยิ่งสำหรับการเลื่อนแนวนอน)- แฟล็ก
reverseScrolling: เลือกว่าจะกลับทิศทางการเลื่อนหรือไม่
นอกจากจะกลับเดลต้าการเลื่อนแล้ว scrollableArea ยังตัดเนื้อหาให้พอดีกับขอบเขตของเลย์เอาต์และจัดการการแสดงผลเอฟเฟกต์การเลื่อนเกิน โดยค่าเริ่มต้น ระบบจะใช้เอฟเฟกต์ที่ LocalOverscrollFactory มีให้
คุณสามารถปรับแต่งหรือปิดใช้เอฟเฟกต์นี้ได้โดยใช้การโอเวอร์โหลด scrollableArea
ที่ยอมรับพารามิเตอร์ OverscrollEffect
ควรใช้ตัวแก้ไข scrollableArea เมื่อใด
คุณควรใช้ตัวแก้ไข scrollableArea เมื่อต้องการสร้างคอมโพเนนต์การเลื่อนที่กำหนดเองซึ่งตัวแก้ไข horizontalScroll หรือ verticalScroll หรือเลย์เอาต์แบบ Lazy ไม่สามารถรองรับได้อย่างเพียงพอ ซึ่งมักจะเกี่ยวข้องกับกรณีต่อไปนี้
- ตรรกะเลย์เอาต์ที่กำหนดเอง: เมื่อการจัดเรียงไอเทมเปลี่ยนแปลงแบบไดนามิก ตามตำแหน่งการเลื่อน
- เอฟเฟกต์ภาพที่ไม่เหมือนใคร: การใช้การแปลง การปรับขนาด หรือเอฟเฟกต์อื่นๆ กับองค์ประกอบย่อยขณะเลื่อน
- การควบคุมโดยตรง: ต้องการการควบคุมกลไกการเลื่อนอย่างละเอียด
นอกเหนือจากที่
verticalScrollหรือเลย์เอาต์แบบ Lazy แสดง
สร้างรายการที่กำหนดเองคล้ายวงล้อโดยใช้ scrollableArea
ตัวอย่างต่อไปนี้แสดงการใช้ scrollableArea เพื่อสร้างรายการแนวตั้งที่กำหนดเองซึ่งไอเทมจะเล็กลงเมื่อเคลื่อนที่ออกจากตรงกลาง ทำให้เกิดเอฟเฟกต์ภาพ "คล้ายวงล้อ" การแปลงที่ขึ้นอยู่กับการเลื่อนแบบนี้เป็นกรณีการใช้งานที่เหมาะสำหรับ 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 } } } } // ...
ตัวแก้ไขการเลื่อนได้
ตัวปรับแต่ง scrollable แตกต่างจากตัวปรับแต่งการเลื่อนตรงที่ scrollable จะตรวจจับท่าทางสัมผัสเพื่อเลื่อนและบันทึกเดลต้า แต่จะไม่ชดเชยเนื้อหาโดยอัตโนมัติ ระบบจะมอบหมายหน้าที่นี้ให้กับผู้ใช้ผ่าน
ScrollableState
ซึ่งจำเป็นเพื่อให้ตัวแก้ไขนี้ทำงานได้อย่างถูกต้อง
เมื่อสร้าง ScrollableState คุณต้องระบุฟังก์ชัน consumeScrollDelta ซึ่งจะเรียกใช้ในแต่ละขั้นตอนการเลื่อน (โดยอินพุตท่าทางสัมผัส การเลื่อนอย่างราบรื่น หรือการปัด) พร้อมเดลต้าเป็นพิกเซล ฟังก์ชันนี้ต้องแสดงระยะการเลื่อนที่ใช้ไป เพื่อให้มั่นใจว่าระบบจะเผยแพร่เหตุการณ์อย่างถูกต้องในกรณีที่มีองค์ประกอบที่ซ้อนกันซึ่งมีตัวแก้ไข scrollable
ข้อมูลโค้ดต่อไปนี้จะตรวจจับท่าทางสัมผัสและแสดงค่าตัวเลขสำหรับการชดเชย แต่จะไม่ชดเชยองค์ประกอบใดๆ
@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()) } }
แนะนำสำหรับคุณ
- หมายเหตุ: ข้อความลิงก์จะแสดงเมื่อ JavaScript ปิดอยู่
- ทำความเข้าใจท่าทางสัมผัส
- ย้ายข้อมูล
CoordinatorLayoutไปยัง Compose - การใช้ View ใน Compose