ในการพลิกผ่านเนื้อหาในลักษณะซ้ายและขวาหรือขึ้นและลง คุณสามารถใช้
เวลา
HorizontalPager
และ
VerticalPager
Composable ตามลำดับ Composable เหล่านี้มีหน้าที่คล้ายกับ
ViewPager
ในข้อมูลพร็อพเพอร์ตี้
ระบบ โดยค่าเริ่มต้น HorizontalPager
จะใช้ความกว้างของหน้าจอ
VerticalPager
จะใช้ความสูงสูงสุด และเพจเจอร์ที่เลื่อนได้ 1 หน้าเท่านั้น
ค่าเริ่มต้นเหล่านี้กำหนดค่าได้ทั้งหมด
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 Loading
หน้าเว็บทั้งใน HorizontalPager
และ VerticalPager
ทำงานแบบ Lazy Loading
เขียนและจัดวางเมื่อจำเป็น ในฐานะผู้ใช้
Composable จะนำหน้าที่ไม่ได้ใช้แล้ว
ต้องระบุ
โหลดหน้าเพิ่มเติมนอกหน้าจอ
โดยค่าเริ่มต้น เพจเจอร์จะโหลดเฉพาะหน้าที่มองเห็นได้บนหน้าจอ เพื่อโหลดหน้าเพิ่มเติม
ตั้งค่า 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
เพื่อสังเกตการเปลี่ยนแปลงของตัวแปรเหล่านี้ได้
และโต้ตอบกับพวกเขา ตัวอย่างเช่น หากต้องการส่งเหตุการณ์ Analytics เมื่อเปลี่ยนแปลงหน้าเว็บแต่ละครั้ง
คุณสามารถทำสิ่งต่อไปนี้ได้
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
จะใช้เป็นตัวอย่างเท่านั้น คุณสามารถตั้งค่า
ระหว่างขนาดระยะห่างระหว่างขอบแต่ละจุดให้กับค่าใดๆ
ปรับแต่งลักษณะการเลื่อน
Composable ของ HorizontalPager
และ VerticalPager
เริ่มต้นจะระบุวิธี
ท่าทางสัมผัสการเลื่อนใช้ได้กับเพจเจอร์ แต่คุณสามารถปรับแต่งและเปลี่ยน
ค่าเริ่มต้น เช่น pagerSnapDistance
หรือ flingBehavior
ระยะการสแนป
ตามค่าเริ่มต้น HorizontalPager
และ VerticalPager
จะกำหนดจำนวนสูงสุด
หน้าเว็บที่ท่าทางสัมผัสการสะบัดสามารถเลื่อนผ่านไปยังหน้าได้ครั้งละ 1 หน้า หากต้องการเปลี่ยน
ตั้งค่านี้
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), beyondBoundsPageCount = 10, flingBehavior = fling ) { PagerSampleItem(page = it) } }
แนะนำสำหรับคุณ
- หมายเหตุ: ข้อความลิงก์จะแสดงเมื่อ JavaScript ปิดอยู่
- ConstraintLayout ในการเขียน
- ตัวปรับแต่งกราฟิก
- ย้ายข้อมูล
CoordinatorLayout
ไปยัง Compose