หากต้องการเลื่อนดูเนื้อหาไปทางซ้ายและขวาหรือขึ้นและลง คุณสามารถใช้คอมโพสิเบิล HorizontalPager
และ VerticalPager
ตามลำดับ คอมโพสิชันเหล่านี้มีฟังก์ชันการทำงานคล้ายกับ ViewPager
ในระบบมุมมอง โดยค่าเริ่มต้น HorizontalPager
จะกินพื้นที่ความกว้างของหน้าจอทั้งหมด VerticalPager
จะกินพื้นที่ความสูงของหน้าจอทั้งหมด และตัวเลื่อนหน้าเว็บจะเลื่อนหน้าเว็บทีละหน้าเท่านั้น ค่าเริ่มต้นเหล่านี้ทั้งหมดสามารถกําหนดค่าได้
HorizontalPager
หากต้องการสร้างตัวแบ่งหน้าที่จะเลื่อนไปทางซ้ายและขวาในแนวนอน ให้ใช้ตัวเลือกต่อไปนี้
HorizontalPager
// Display 10 items val pagerState = rememberPagerState(pageCount = { 10 }) HorizontalPager(state = pagerState) { page -> // Our page content Text( text = "Page: $page", modifier = Modifier.fillMaxWidth() ) }
VerticalPager
หากต้องการสร้างตัวแบ่งหน้าที่จะเลื่อนขึ้นและลง ให้ใช้ VerticalPager
ดังนี้
// Display 10 items val pagerState = rememberPagerState(pageCount = { 10 }) VerticalPager(state = pagerState) { page -> // Our page content Text( text = "Page: $page", modifier = Modifier.fillMaxWidth() ) }
การสร้างแบบ Lazy
หน้าเว็บทั้งใน HorizontalPager
และ VerticalPager
จะคอมไพล์แบบไม่ใช้ทรัพยากรและจัดวางเมื่อจำเป็น เมื่อผู้ใช้เลื่อนดูหน้าต่างๆ คอมโพสิเบิลจะนำหน้าเว็บที่ไม่จําเป็นออก
โหลดหน้าเว็บเพิ่มเติมนอกหน้าจอ
โดยค่าเริ่มต้น ตัวแบ่งหน้าจะโหลดเฉพาะหน้าที่มองเห็นบนหน้าจอเท่านั้น หากต้องการโหลดหน้าเว็บเพิ่มเติมที่ไม่ได้อยู่ในหน้าจอ ให้ตั้งค่า beyondBoundsPageCount
เป็นค่าที่มากกว่า 0
เลื่อนไปยังรายการในโปรแกรมแบ่งหน้า
หากต้องการเลื่อนไปยังหน้าที่ต้องการในโปรแกรมเลื่อนหน้า ให้สร้างออบเจ็กต์ PagerState
โดยใช้ rememberPagerState()
แล้วส่งผ่านเป็นพารามิเตอร์ state
ไปยังโปรแกรมเลื่อนหน้า คุณสามารถเรียกใช้ PagerState#scrollToPage()
ในสถานะนี้ภายใน CoroutineScope
ได้ดังนี้
val pagerState = rememberPagerState(pageCount = { 10 }) HorizontalPager(state = pagerState) { page -> // Our page content Text( text = "Page: $page", modifier = Modifier .fillMaxWidth() .height(100.dp) ) } // scroll to page val coroutineScope = rememberCoroutineScope() Button(onClick = { coroutineScope.launch { // Call scroll to on pagerState pagerState.scrollToPage(5) } }, modifier = Modifier.align(Alignment.BottomCenter)) { Text("Jump to Page 5") }
หากต้องการแสดงภาพเคลื่อนไหวไปยังหน้าเว็บ ให้ใช้ฟังก์ชัน PagerState#animateScrollToPage()
ดังนี้
val pagerState = rememberPagerState(pageCount = { 10 }) HorizontalPager(state = pagerState) { page -> // Our page content Text( text = "Page: $page", modifier = Modifier .fillMaxWidth() .height(100.dp) ) } // scroll to page val coroutineScope = rememberCoroutineScope() Button(onClick = { coroutineScope.launch { // Call scroll to on pagerState pagerState.animateScrollToPage(5) } }, modifier = Modifier.align(Alignment.BottomCenter)) { Text("Jump to Page 5") }
รับการแจ้งเตือนเกี่ยวกับการเปลี่ยนแปลงสถานะของหน้าเว็บ
PagerState
มีพร็อพเพอร์ตี้ 3 รายการที่มีข้อมูลเกี่ยวกับหน้าเว็บ ได้แก่
currentPage
,
settledPage
และ
targetPage
currentPage
: หน้าเว็บที่อยู่ใกล้กับตำแหน่งการจับภาพมากที่สุด โดยค่าเริ่มต้น ตำแหน่งการยึดจะอยู่ที่จุดเริ่มต้นของเลย์เอาต์settledPage
: หมายเลขหน้าเว็บเมื่อไม่มีภาพเคลื่อนไหวหรือการเลื่อน การดำเนินการนี้แตกต่างจากพร็อพเพอร์ตี้currentPage
ตรงที่currentPage
จะอัปเดตทันทีหากหน้าเว็บอยู่ใกล้กับตำแหน่งการยึดมากพอ แต่settledPage
จะยังคงเหมือนเดิมจนกว่าภาพเคลื่อนไหวทั้งหมดจะเล่นเสร็จtargetPage
: ตำแหน่งหยุดที่แนะนำสำหรับการเลื่อน
คุณสามารถใช้ฟังก์ชัน snapshotFlow
เพื่อสังเกตการเปลี่ยนแปลงของตัวแปรเหล่านี้และดำเนินการกับการเปลี่ยนแปลงได้ ตัวอย่างเช่น หากต้องการส่งเหตุการณ์การวิเคราะห์เมื่อหน้าเว็บมีการเปลี่ยนแปลง คุณทําสิ่งต่อไปนี้ได้
val pagerState = rememberPagerState(pageCount = { 10 }) LaunchedEffect(pagerState) { // Collect from the a snapshotFlow reading the currentPage snapshotFlow { pagerState.currentPage }.collect { page -> // Do something with each page change, for example: // viewModel.sendPageSelectedEvent(page) Log.d("Page change", "Page changed to $page") } } VerticalPager( state = pagerState, ) { page -> Text(text = "Page: $page") }
เพิ่มตัวบ่งชี้หน้า
หากต้องการเพิ่มตัวบ่งชี้ลงในหน้าเว็บ ให้ใช้ออบเจ็กต์ PagerState
เพื่อรับข้อมูลเกี่ยวกับหน้าที่เลือกจากจำนวนหน้าเว็บทั้งหมด แล้ววาดตัวบ่งชี้ที่กําหนดเอง
ตัวอย่างเช่น หากต้องการตัวบ่งชี้วงกลมแบบง่าย คุณสามารถใส่วงกลมซ้ำๆ และเปลี่ยนสีวงกลมโดยอิงตามการเลือกหน้าเว็บได้โดยใช้pagerState.currentPage
ดังนี้
val pagerState = rememberPagerState(pageCount = { 4 }) HorizontalPager( state = pagerState, modifier = Modifier.fillMaxSize() ) { page -> // Our page content Text( text = "Page: $page", ) } Row( Modifier .wrapContentHeight() .fillMaxWidth() .align(Alignment.BottomCenter) .padding(bottom = 8.dp), horizontalArrangement = Arrangement.Center ) { repeat(pagerState.pageCount) { iteration -> val color = if (pagerState.currentPage == iteration) Color.DarkGray else Color.LightGray Box( modifier = Modifier .padding(2.dp) .clip(CircleShape) .background(color) .size(16.dp) ) } }
ใช้เอฟเฟกต์การเลื่อนรายการกับเนื้อหา
กรณีการใช้งานทั่วไปคือการใช้ตําแหน่งการเลื่อนเพื่อใช้เอฟเฟกต์กับรายการในโปรแกรมเลื่อน หากต้องการดูว่าหน้าเว็บอยู่ห่างจากหน้าที่เลือกอยู่ในปัจจุบันเพียงใด ให้ใช้ PagerState.currentPageOffsetFraction
จากนั้นคุณสามารถใช้เอฟเฟกต์การเปลี่ยนรูปแบบกับเนื้อหาโดยอิงตามระยะห่างจากหน้าที่เลือก
เช่น หากต้องการปรับความทึบของรายการตามระยะห่างจากศูนย์ ให้เปลี่ยน alpha
โดยใช้ Modifier.graphicsLayer
ในรายการภายในตัวแบ่งหน้า
val pagerState = rememberPagerState(pageCount = { 4 }) HorizontalPager(state = pagerState) { page -> Card( Modifier .size(200.dp) .graphicsLayer { // Calculate the absolute offset for the current page from the // scroll position. We use the absolute value which allows us to mirror // any effects for both directions val pageOffset = ( (pagerState.currentPage - page) + pagerState .currentPageOffsetFraction ).absoluteValue // We animate the alpha, between 50% and 100% alpha = lerp( start = 0.5f, stop = 1f, fraction = 1f - pageOffset.coerceIn(0f, 1f) ) } ) { // Card content } }
ขนาดหน้าที่กำหนดเอง
โดยค่าเริ่มต้น HorizontalPager
และ VerticalPager
จะใช้ความกว้างหรือความสูงเต็มตามลำดับ คุณสามารถตั้งค่าตัวแปร pageSize
ให้มีค่า Fixed
, Fill
(ค่าเริ่มต้น) หรือการคํานวณขนาดที่กําหนดเอง
ตัวอย่างเช่น หากต้องการตั้งค่าหน้าเว็บที่มีความกว้างคงที่ 100.dp
ให้ทำดังนี้
val pagerState = rememberPagerState(pageCount = { 4 }) HorizontalPager( state = pagerState, pageSize = PageSize.Fixed(100.dp) ) { page -> // page content }
หากต้องการปรับขนาดหน้าเว็บตามขนาดวิวพอร์ต ให้ใช้การคํานวณขนาดหน้าเว็บที่กําหนดเอง สร้างออบเจ็กต์ PageSize
ที่กําหนดเอง แล้วหาร availableSpace
ด้วย 3 โดยคํานึงถึงระยะห่างระหว่างรายการ
private val threePagesPerViewport = object : PageSize { override fun Density.calculateMainAxisPageSize( availableSpace: Int, pageSpacing: Int ): Int { return (availableSpace - 2 * pageSpacing) / 3 } }
การเว้นวรรคเนื้อหา
ทั้ง HorizontalPager
และ VerticalPager
รองรับการเปลี่ยนระยะห่างจากขอบของเนื้อหา ซึ่งช่วยให้คุณกำหนดขนาดสูงสุดและการจัดแนวของหน้าได้
ตัวอย่างเช่น การตั้งค่าระยะขอบ start
จะจัดแนวหน้าเว็บไว้ที่ส่วนท้าย
val pagerState = rememberPagerState(pageCount = { 4 }) HorizontalPager( state = pagerState, contentPadding = PaddingValues(start = 64.dp), ) { page -> // page content }
การตั้งค่าระยะห่างจากขอบทั้ง start
และ end
เป็นค่าเดียวกันจะจัดวางรายการในแนวนอนให้อยู่ตรงกลาง
val pagerState = rememberPagerState(pageCount = { 4 }) HorizontalPager( state = pagerState, contentPadding = PaddingValues(horizontal = 32.dp), ) { page -> // page content }
การตั้งค่าระยะขอบ end
จะจัดแนวหน้าเว็บไว้ที่จุดเริ่มต้น
val pagerState = rememberPagerState(pageCount = { 4 }) HorizontalPager( state = pagerState, contentPadding = PaddingValues(end = 64.dp), ) { page -> // page content }
คุณสามารถกําหนดค่า top
และ bottom
เพื่อให้ได้ผลลัพธ์ที่คล้ายกันสําหรับ VerticalPager
ค่า 32.dp
ใช้เป็นตัวอย่างเท่านั้น คุณตั้งค่ามิติข้อมูลระยะห่างจากขอบแต่ละรายการเป็นค่าใดก็ได้
ปรับแต่งลักษณะการเลื่อน
คอมโพสิเบิล HorizontalPager
และ VerticalPager
เริ่มต้นจะระบุวิธีใช้ท่าทางสัมผัสในการเลื่อนกับโปรแกรมเลื่อนหน้า แต่คุณสามารถปรับแต่งและเปลี่ยนแปลงค่าเริ่มต้นได้ เช่น pagerSnapDistance
หรือ flingBehavior
ระยะการจับภาพ
โดยค่าเริ่มต้น HorizontalPager
และ VerticalPager
จะตั้งค่าจำนวนหน้าสูงสุดที่ท่าทางสัมผัสด้วยการปัดสามารถเลื่อนผ่านได้ทีละหน้า หากต้องการเปลี่ยนค่านี้ ให้ตั้งค่า pagerSnapDistance
ใน flingBehavior
ดังนี้
val pagerState = rememberPagerState(pageCount = { 10 }) val fling = PagerDefaults.flingBehavior( state = pagerState, pagerSnapDistance = PagerSnapDistance.atMost(10) ) Column(modifier = Modifier.fillMaxSize()) { HorizontalPager( state = pagerState, pageSize = PageSize.Fixed(200.dp), beyondViewportPageCount = 10, flingBehavior = fling ) { PagerSampleItem(page = it) } }
แนะนำสำหรับคุณ
- หมายเหตุ: ข้อความลิงก์จะแสดงเมื่อ JavaScript ปิดอยู่
- ConstraintLayout ใน Compose
- ตัวแก้ไขกราฟิก
- ย้ายข้อมูล
CoordinatorLayout
ไปยัง "เขียน"