Penomoran memungkinkan pengguna menggeser secara horizontal atau vertikal di antara halaman layar penuh yang berbeda di perangkat Wear OS. Kasus penggunaan umum mencakup menggeser antara metrik latihan fisik dan kontrol media di aplikasi latihan fisik, atau menelusuri alur multi-halaman.
Di Compose untuk Wear OS Material 3, HorizontalPagerScaffold dan
VerticalPagerScaffold mengoordinasikan tata letak penomoran halaman, secara otomatis
memosisikan indikator halaman dan mengelola transisi dengan TimeText.
Setiap halaman di-wrap dalam composable AnimatedPage, yang menerapkan
penskalaan, pengubahan bentuk sudut bulat, dan efek scrim saat halaman bertransisi di
layar bulat.
Animasi berikut menunjukkan cara HorizontalPagerScaffold dan AnimatedPage
menskalakan dan menganimasikan halaman selama geser horizontal:
Hierarki scaffold untuk penomoran halaman
Saat mendesain tata letak layar yang dipaginasi di Material 3—baik menggeser
ke kiri atau kanan (HorizontalPager) maupun ke atas atau bawah (VerticalPager)—gunakan
hierarki komponen berikut dari penampung luar ke konten dalam:
AppScaffold: Penampung terluar di root aplikasi Anda (hanya gunakan satu per aplikasi). Hal ini menyematkan overlayTimeTextglobal sehingga jam tetap berada di bagian atas layar selama transisi halaman dan gestur geser untuk menutup.HorizontalPagerScaffoldatauVerticalPagerScaffold: Ditempatkan di dalamAppScaffolddi tingkat pager. Fungsi ini mengoordinasikan transisi antaraTimeTextdanHorizontalPageIndicatoratauVerticalPageIndicator.HorizontalPageratauVerticalPager: Penampung pager dasar yang mengelola gestur geser, fisika lemparan, dan penyesuaian input putar menggunakanPagerStatebersama.AnimatedPage: Ditempatkan di dalam lambda konten halaman pager. Komponen ini membungkus setiap halaman individual untuk menerapkan animasi transisi Material 3 (efek penskalaan dan scrim) berdasarkan offset halaman diPagerState.ScreenScaffold: Ditempatkan di dalamAnimatedPageuntuk setiap halaman individual. Karena setiap halaman dapat berisi daftar yang dapat di-scroll secara vertikal (sepertiTransformingLazyColumn) atauEdgeButton-nya sendiri, menyusunScreenScaffolddi dalam setiap halaman memastikan bahwa indikator scroll vertikal, tombol tepi, dancontentPaddingtermasuk dalam halaman tertentu tersebut dan beranimasi dengan lancar.
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)
Mengimplementasikan pager horizontal
Untuk menerapkan pager horizontal di Material 3, susun HorizontalPagerScaffold,
HorizontalPager, AnimatedPage, dan ScreenScaffold di dalam
AppScaffold aplikasi Anda.
Gunakan PagerScaffoldDefaults.snapWithSpringFlingBehavior untuk
flingBehavior guna menerapkan fisika gerakan pegas Material 3 dan penyesuaian halaman responsif (HighSnapPositionalThreshold). Secara default, HorizontalPager menonaktifkan
scroll halaman putar (rotaryScrollableBehavior = null), sehingga input putar
kenop jam atau bingkai dapat men-scroll daftar vertikal (seperti
TransformingLazyColumn) di dalam halaman aktif.
Contoh berikut menunjukkan penyiapan HorizontalPagerScaffold lengkap:
@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") } } } } } } } } }
Jika halaman di dalam pager horizontal Anda berisi TransformingLazyColumn,
buat rememberTransformingLazyColumnState() terpisah di dalam cakupan
halaman tersebut dan teruskan ke ScreenScaffold dan TransformingLazyColumn bagian dalam:
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") } } } } } } } } }
Menerapkan pager vertikal
Pager vertikal memungkinkan pengguna menggeser ke atas dan ke bawah antarhalaman atau menelusurinya menggunakan tombol samping atau bezel berputar smartwatch.
Tidak seperti HorizontalPager, VerticalPager memungkinkan penyesuaian halaman rotari secara
default (RotaryScrollableDefaults.snapBehavior(state)). Teruskan
PagerScaffoldDefaults.snapWithSpringFlingBehavior ke flingBehavior dan bungkus
setiap halaman dalam AnimatedPage dan 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") } } } } } } }
Menyesuaikan perilaku penomoran halaman
Anda dapat menyesuaikan sensitivitas penarikan HorizontalPagerScaffold dan
VerticalPagerScaffold agar sesuai dengan kebutuhan interaksi aplikasi Anda.
Menyesuaikan sensitivitas penarikan untuk latihan fisik
Selama latihan fisik atau aktivitas dengan gerakan tinggi yang membatasi kontrol motorik kasar pengguna, sentuhan yang tidak disengaja atau sedikit putaran kenop dapat secara tidak sengaja mengganti halaman. Untuk layar ini, konfigurasi pager Anda dengan sensitivitas penarikan rendah:
- Lewati
PagerDefaults.snapFlingBehaviordenganmaxFlingPages = 0dansnapPositionalThreshold = PagerScaffoldDefaults.LowSnapPositionalThresholdsehingga penarikan yang disengaja di sebagian besar layar diperlukan untuk membuka halaman. - Jika Anda mengaktifkan penyelarasan halaman putar, tetapkan
snapSensitivity = RotaryScrollableDefaults.LowSnapSensitivitydiRotaryScrollableDefaults.snapBehavioruntuk memerlukan lebih banyak rotasi sebelum menyelaraskan ke halaman berikutnya.
@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 } } } } } }
Untuk implementasi contoh lengkap, lihat Pager.kt di repositori android/snippets dan PagerScaffoldSample.kt di repositori AndroidX.