การแบ่งหน้าช่วยให้ผู้ใช้ปัดในแนวนอนหรือแนวตั้งระหว่างหน้าจอแบบเต็ม ที่แตกต่างกันบนอุปกรณ์ Wear OS กรณีการใช้งานที่พบบ่อย ได้แก่ การปัดระหว่างเมตริกการออกกำลังกาย และการควบคุมสื่อในแอปออกกำลังกาย หรือการไปยังโฟลว์แบบหลายหน้า
ใน Compose สำหรับ Wear OS Material 3 HorizontalPagerScaffold และ
VerticalPagerScaffold จะประสานงานเลย์เอาต์ของ Pager โดยจะจัดตำแหน่งตัวบ่งหน้าและจัดการการเปลี่ยนโดยอัตโนมัติด้วย TimeText
แต่ละหน้าจะอยู่ใน Composable AnimatedPage ซึ่งใช้
การปรับขนาด การเปลี่ยนมุมโค้ง และเอฟเฟกต์ขอบมืดเมื่อหน้าเปลี่ยนผ่าน
จอแสดงผลทรงกลม
ภาพเคลื่อนไหวต่อไปนี้แสดงวิธีที่ HorizontalPagerScaffold และ AnimatedPage
ปรับขนาดและเคลื่อนไหวหน้าเว็บระหว่างการปัดในแนวนอน
โครงสร้างลำดับชั้นสำหรับการแบ่งหน้า
เมื่อออกแบบเลย์เอาต์หน้าจอแบบแบ่งหน้าใน Material 3 ไม่ว่าจะปัดไปทางซ้ายหรือขวา (HorizontalPager) หรือขึ้นหรือลง (VerticalPager) ให้ใช้ลำดับชั้นของคอมโพเนนต์ต่อไปนี้จากคอนเทนเนอร์ด้านนอกไปยังเนื้อหาด้านใน
AppScaffold: คอนเทนเนอร์นอกสุดที่รูทของแอป (ใช้เพียง 1 รายการต่อแอป) โดยจะยึดTimeTextภาพซ้อนทับส่วนกลางเพื่อให้ นาฬิกาคงที่ที่ด้านบนของหน้าจอในระหว่างการเปลี่ยนหน้า และท่าทางสัมผัสปัดเพื่อปิดHorizontalPagerScaffoldหรือVerticalPagerScaffold: วางไว้ ภายในAppScaffoldที่ระดับเพจเจอร์ โดยจะประสานงานการเปลี่ยนผ่านระหว่างTimeTextกับHorizontalPageIndicatorหรือVerticalPageIndicatorHorizontalPagerหรือVerticalPager: คอนเทนเนอร์ Pager พื้นฐาน ที่จัดการท่าทางสัมผัสการปัด ฟิสิกส์การสะบัด และการสแนปการใส่ข้อมูลด้วยปุ่มหมุน โดยใช้PagerStateที่ใช้ร่วมกันAnimatedPage: วางไว้ใน Lambda เนื้อหาหน้าของเครื่องมือเปลี่ยนหน้า โดยจะ ครอบแต่ละหน้าเพื่อใช้ภาพเคลื่อนไหวการเปลี่ยนหน้าของ Material 3 (เอฟเฟกต์การปรับขนาดและเลเยอร์มืด) ตามออฟเซ็ตของหน้าในPagerStateScreenScaffold: วางภายในAnimatedPageสำหรับแต่ละหน้า แต่ละหน้า เนื่องจากแต่ละหน้าอาจมีรายการที่เลื่อนได้ในแนวตั้งของตัวเอง (เช่นTransformingLazyColumn) หรือEdgeButtonของตัวเอง การซ้อนScreenScaffoldภายในแต่ละหน้าจะช่วยให้มั่นใจได้ว่าตัวบ่งชี้การเลื่อนแนวตั้ง ปุ่มขอบ และcontentPaddingจะเป็นของหน้าเว็บนั้นๆ และเคลื่อนไหวไปพร้อมกับหน้าเว็บอย่างราบรื่น
AppScaffold (1 per app: anchors global TimeText)
└── HorizontalPagerScaffold / VerticalPagerScaffold (manages PageIndicator)
└── HorizontalPager / VerticalPager (manages PagerState & fling behavior)
└── AnimatedPage (applies scaling & scrim transitions per page)
└── ScreenScaffold (1 per page: ScrollIndicator & EdgeButton)
└── Page Content (Column or TransformingLazyColumn)
ใช้เพจเจอร์แนวนอน
หากต้องการใช้เพจเจอร์แนวนอนใน Material 3 ให้ซ้อน HorizontalPagerScaffold,
HorizontalPager, AnimatedPage และ ScreenScaffold ไว้ใน
AppScaffold ของแอป
ใช้ PagerScaffoldDefaults.snapWithSpringFlingBehavior สำหรับ
flingBehavior เพื่อใช้ฟิสิกส์การเคลื่อนไหวแบบสปริงของ Material 3 และการสแนปหน้าเว็บที่ตอบสนอง (HighSnapPositionalThreshold) โดยค่าเริ่มต้น HorizontalPager จะปิดใช้
การเลื่อนหน้าแบบหมุน (rotaryScrollableBehavior = null) ซึ่งจะช่วยให้การหมุน
เม็ดมะยมหรือการป้อนข้อมูลขอบจอเลื่อนรายการแนวตั้ง (เช่น TransformingLazyColumn) ภายในหน้าเว็บที่ใช้งานอยู่ได้
ตัวอย่างต่อไปนี้แสดงการตั้งค่า HorizontalPagerScaffold ที่สมบูรณ์
@Composable fun HorizontalPagerScaffoldSample(navigateBack: () -> Unit) { AppScaffold { val pagerState = rememberPagerState(pageCount = { 10 }) HorizontalPagerScaffold(pagerState = pagerState) { HorizontalPager( state = pagerState, flingBehavior = PagerScaffoldDefaults.snapWithSpringFlingBehavior( state = pagerState ), ) { page -> AnimatedPage(pageIndex = page, pagerState = pagerState) { ScreenScaffold { Column( modifier = Modifier.fillMaxSize(), horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Center, ) { Text(text = "Page #$page") Spacer(modifier = Modifier.height(8.dp)) Text(text = "Swipe left and right") if (page == 0) { Spacer(modifier = Modifier.height(16.dp)) Button(onClick = navigateBack) { Text("Exit") } } } } } } } } }
หากหน้าภายในเพจเจอร์แนวนอนมี TransformingLazyColumn
ให้สร้าง rememberTransformingLazyColumnState() แยกต่างหากภายในขอบเขตของหน้าเว็บนั้น
แล้วส่งไปยัง ScreenScaffold และ TransformingLazyColumn ด้านใน
AppScaffold { val pagerState = rememberPagerState(pageCount = { 10 }) HorizontalPagerScaffold(pagerState = pagerState) { HorizontalPager( state = pagerState, flingBehavior = PagerScaffoldDefaults.snapWithSpringFlingBehavior( state = pagerState ), ) { page -> AnimatedPage(pageIndex = page, pagerState = pagerState) { val columnState = rememberTransformingLazyColumnState() val transformationSpec = rememberTransformationSpec() ScreenScaffold( scrollState = columnState, ) { contentPadding -> TransformingLazyColumn( state = columnState, contentPadding = contentPadding, ) { item { ListHeader( modifier = Modifier .fillMaxWidth() .transformedHeight(this, transformationSpec) .minimumVerticalContentPadding( ListHeaderDefaults.minimumTopListContentPadding ), transformation = SurfaceTransformation(transformationSpec), ) { Text(text = "Pager sample") } } item { Card( modifier = Modifier .fillMaxWidth() .transformedHeight(this, transformationSpec) .minimumVerticalContentPadding( CardDefaults.minimumVerticalListContentPadding ), transformation = SurfaceTransformation(transformationSpec), ) { if (page == 0) { Text(text = "Page #$page. Swipe right") } else { Text(text = "Page #$page. Swipe left and right") } } } } } } } } }
ใช้เพจเจอร์แนวตั้ง
เครื่องมือเปลี่ยนหน้าแนวตั้งช่วยให้ผู้ใช้ปัดขึ้นและลงระหว่างหน้าต่างๆ หรือเลื่อนผ่านหน้าต่างๆ ได้ โดยใช้ปุ่มด้านข้างแบบหมุนหรือขอบหน้าปัดของนาฬิกา
VerticalPager ช่วยให้เปิดใช้การสแนปหน้าแบบหมุนได้โดยค่าเริ่มต้น (RotaryScrollableDefaults.snapBehavior(state)) ซึ่งแตกต่างจาก HorizontalPager ส่ง PagerScaffoldDefaults.snapWithSpringFlingBehavior ไปยัง flingBehavior และห่อหุ้มแต่ละหน้าใน AnimatedPage และ ScreenScaffold
@Composable fun VerticalPagerScaffoldSample() { AppScaffold { val pagerState = rememberPagerState(pageCount = { 10 }) VerticalPagerScaffold(pagerState = pagerState) { VerticalPager( state = pagerState, flingBehavior = PagerScaffoldDefaults.snapWithSpringFlingBehavior( state = pagerState ), ) { page -> AnimatedPage(pageIndex = page, pagerState = pagerState) { ScreenScaffold { Column( modifier = Modifier.fillMaxSize(), horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Center, ) { Text(text = "Page #$page") Spacer(modifier = Modifier.height(8.dp)) Text(text = "Swipe up and down") } } } } } } }
ปรับแต่งลักษณะการทำงานของเพจเจอร์
คุณปรับแต่งความไวในการสแนปของ HorizontalPagerScaffold และ
VerticalPagerScaffold ให้ตรงกับความต้องการในการโต้ตอบของแอปได้
ปรับความไวในการสแนปสำหรับการออกกำลังกาย
ในระหว่างการออกกำลังกายหรือกิจกรรมที่มีการเคลื่อนไหวสูงซึ่งการควบคุมการเคลื่อนไหวขั้นต้นของผู้ใช้ ถูกจำกัด การสัมผัสโดยไม่ตั้งใจหรือการหมุนเม็ดมะยมเล็กน้อยอาจเปลี่ยนหน้าโดยไม่ตั้งใจ สำหรับหน้าจอเหล่านี้ ให้กำหนดค่าเพจเจอร์ที่มีความไวในการสแนปต่ำ
- ปัด
PagerDefaults.snapFlingBehaviorด้วยmaxFlingPages = 0และsnapPositionalThreshold = PagerScaffoldDefaults.LowSnapPositionalThresholdจึงต้องลากข้ามส่วนที่ใหญ่กว่าของหน้าจอเพื่อ เปลี่ยนหน้า - หากเปิดใช้การสแนปหน้าแบบหมุน ให้ตั้งค่า
snapSensitivity = RotaryScrollableDefaults.LowSnapSensitivityในRotaryScrollableDefaults.snapBehaviorเพื่อกำหนดให้ต้องหมุนมากขึ้นก่อน สแนปไปยังหน้าถัดไป
@Composable fun HorizontalPagerScaffoldWithLowSensitivitySample(navigateBack: () -> Unit) { AppScaffold { val pagerState = rememberPagerState(pageCount = { 3 }) HorizontalPagerScaffold(pagerState = pagerState) { HorizontalPager( state = pagerState, flingBehavior = PagerDefaults.snapFlingBehavior( state = pagerState, maxFlingPages = 0, snapPositionalThreshold = PagerScaffoldDefaults.LowSnapPositionalThreshold, ), rotaryScrollableBehavior = RotaryScrollableDefaults.snapBehavior( pagerState = pagerState, snapSensitivity = RotaryScrollableDefaults.LowSnapSensitivity, ), ) { page -> AnimatedPage(pageIndex = page, pagerState = pagerState) { ScreenScaffold { // Page content } } } } } }
ดูตัวอย่างการติดตั้งใช้งานทั้งหมดได้ที่ Pager.kt ในที่เก็บ android/snippets
และ PagerScaffoldSample.kt ในที่เก็บ AndroidX