İçerikler arasında yatay veya dikey olarak gezinmek için HorizontalPager ve VerticalPager bileşenlerini kullanabilirsiniz. Bunlar, görünüm sistemindeki ViewPager ile benzer işlevlere sahiptir. Varsayılan olarak HorizontalPager tam ekran genişliğini, VerticalPager ise tam yüksekliği kaplar. Sayfa gezginleri de tek seferde yalnızca bir sayfa kaydırır. Bu varsayılanların tümü
yapılandırılabilir.
HorizontalPager
Yatay olarak sola ve sağa kaydırılan bir sayfa gezgini oluşturmak için HorizontalPager kullanın:
HorizontalPager
// Display 10 items val pagerState = rememberPagerState(pageCount = { 10 }) HorizontalPager(state = pagerState) { page -> // Our page content Text( text = "Page: $page", modifier = Modifier.fillMaxWidth() ) }
VerticalPager
Yukarı ve aşağı kaydırılan bir sayfa gezgini oluşturmak için VerticalPager kullanın:
VerticalPager
// Display 10 items val pagerState = rememberPagerState(pageCount = { 10 }) VerticalPager(state = pagerState) { page -> // Our page content Text( text = "Page: $page", modifier = Modifier.fillMaxWidth() ) }
Geç oluşturma
Hem HorizontalPager hem de VerticalPager'deki sayfalar gecikmeli olarak oluşturulur ve gerektiğinde düzenlenir. Kullanıcı sayfalar arasında gezinirken composable, artık gerekli olmayan sayfaları kaldırır.
Ekran dışında daha fazla sayfa yükleme
Varsayılan olarak sayfa gezgini yalnızca ekranda görünen sayfaları yükler. Ekran dışında daha fazla sayfa yüklemek için beyondBoundsPageCount değerini sıfırdan büyük bir değere ayarlayın.
Sayfa gezginindeki bir öğeye kaydırma
Sayfa gezgininde belirli bir sayfaya gitmek için rememberPagerState() kullanarak bir PagerState nesnesi oluşturun ve bunu sayfa gezginine state parametresi olarak iletin. Bu durumu, bir CoroutineScope içinde PagerState#scrollToPage() ile çağırabilirsiniz:
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") }
Sayfaya animasyon eklemek istiyorsanız PagerState#animateScrollToPage() işlevini kullanın:
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") }
Sayfa durumu değişiklikleriyle ilgili bildirim alma
PagerState, sayfalar hakkında bilgi içeren üç özelliğe sahiptir:
currentPage, settledPage ve targetPage.
currentPage: Yakalama konumuna en yakın sayfa. Varsayılan olarak, tutturma konumu düzenin başındadır.settledPage: Animasyon veya kaydırma işlemi yapılmadığında sayfa numarası. Bu,currentPageözelliğinden farklıdır. Sayfa, tutturma konumuna yeterince yakınsacurrentPagehemen güncellenir ancaksettledPage, tüm animasyonlar tamamlanana kadar aynı kalır.targetPage: Kaydırma hareketi için önerilen durma konumu.
Bu değişkenlerdeki değişiklikleri gözlemlemek ve bunlara tepki vermek için snapshotFlow işlevini kullanabilirsiniz. Örneğin, her sayfa değişikliğinde bir analiz etkinliği göndermek için aşağıdakileri yapabilirsiniz:
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") }
Sayfa göstergesi ekleme
Bir sayfaya gösterge eklemek için PagerState nesnesini kullanarak sayfa sayısından hangi sayfanın seçildiği hakkında bilgi alın ve özel göstergenizi çizin.
Örneğin, daire göstergesi oluşturmak için daire sayısını tekrarlayabilir ve sayfanın seçili olup olmamasına göre daire rengini değiştirebilirsiniz. Bunun için pagerState.currentPage kullanabilirsiniz:
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) ) } }
İçeriğe öğe kaydırma efektleri uygulama
Yaygın kullanım alanlarından biri, sayfa gezgini öğelerinize efekt uygulamak için kaydırma konumunu kullanmaktır. Bir sayfanın seçilen sayfadan ne kadar uzakta olduğunu öğrenmek için PagerState.currentPageOffsetFraction simgesini kullanabilirsiniz. Ardından, seçilen sayfaya olan mesafeye göre içeriğinize dönüşüm efektleri uygulayabilirsiniz.
Örneğin, öğelerin opaklığını merkeze olan uzaklıklarına göre ayarlamak için sayfa gezginindeki bir öğede Modifier.graphicsLayer kullanarak alpha değerini değiştirin:
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 } }
Özel sayfa boyutları
Varsayılan olarak HorizontalPager ve VerticalPager, sırasıyla tam genişliği veya tam yüksekliği kaplar. pageSize değişkenini Fixed, Fill (varsayılan) veya özel boyut hesaplaması olacak şekilde ayarlayabilirsiniz.
Örneğin, 100.dp boyutunda sabit genişlikli bir sayfa ayarlamak için:
val pagerState = rememberPagerState(pageCount = { 4 }) HorizontalPager( state = pagerState, pageSize = PageSize.Fixed(100.dp) ) { page -> // page content }
Sayfaları görüntü alanı boyutuna göre boyutlandırmak için özel bir sayfa boyutu hesaplaması kullanın. Özel bir PageSize nesnesi oluşturun ve öğeler arasındaki boşluğu hesaba katarak availableSpace değerini üçe bölün:
private val threePagesPerViewport = object : PageSize { override fun Density.calculateMainAxisPageSize( availableSpace: Int, pageSpacing: Int ): Int { return (availableSpace - 2 * pageSpacing) / 3 } }
İçerik dolgusu
HorizontalPager ve VerticalPager, içerik dolgusunu değiştirmeyi destekler. Bu sayede sayfaların maksimum boyutunu ve hizalamasını etkileyebilirsiniz.
Örneğin, start dolgusunu ayarlamak sayfaları sona doğru hizalar:
val pagerState = rememberPagerState(pageCount = { 4 }) HorizontalPager( state = pagerState, contentPadding = PaddingValues(start = 64.dp), ) { page -> // page content }
Hem start hem de end dolgusunu aynı değere ayarlamak, öğeyi yatay olarak ortalar:
val pagerState = rememberPagerState(pageCount = { 4 }) HorizontalPager( state = pagerState, contentPadding = PaddingValues(horizontal = 32.dp), ) { page -> // page content }
end dolgusunu ayarlamak, sayfaları başlangıca doğru hizalar:
val pagerState = rememberPagerState(pageCount = { 4 }) HorizontalPager( state = pagerState, contentPadding = PaddingValues(end = 64.dp), ) { page -> // page content }
VerticalPager için benzer efektler elde etmek üzere top ve bottom değerlerini ayarlayabilirsiniz. 32.dp değeri burada yalnızca örnek olarak kullanılmıştır. Dolgu boyutlarının her birini istediğiniz değere ayarlayabilirsiniz.
Kaydırma davranışını özelleştirme
Varsayılan HorizontalPager ve VerticalPager composable'ları, kaydırma hareketlerinin sayfa gezginiyle nasıl çalıştığını belirtir. Ancak pagerSnapDistance veya flingBehavior gibi varsayılan ayarları özelleştirip değiştirebilirsiniz.
Tutturma mesafesi
Varsayılan olarak HorizontalPager ve VerticalPager, kaydırma hareketinin tek seferde kaydırabileceği maksimum sayfa sayısını bir sayfa olarak ayarlar. Bunu değiştirmek için flingBehavior üzerinde pagerSnapDistance değerini ayarlayın:
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) } }
Otomatik ilerleyen sayfa gezgini oluşturma
Bu bölümde, Compose'da sayfa göstergeleri içeren otomatik ilerleyen bir sayfa gezgini oluşturma işlemi açıklanmaktadır. Öğe koleksiyonu otomatik olarak yatay şekilde kaydırılır ancak kullanıcılar öğeler arasında manuel olarak da kaydırma yapabilir. Kullanıcı sayfa gezginiyle etkileşim kurarsa otomatik ilerleme durdurulur.
Temel örnek
Aşağıdaki snippet'ler birlikte, her sayfanın farklı bir renkte oluşturulduğu, görsel göstergeli temel bir otomatik ilerleyen sayfa gezgini uygulaması oluşturur:
@Composable fun AutoAdvancePager(pageItems: List<Color>, modifier: Modifier = Modifier) { Box(modifier = Modifier.fillMaxSize()) { val pagerState = rememberPagerState(pageCount = { pageItems.size }) val pagerIsDragged by pagerState.interactionSource.collectIsDraggedAsState() val pageInteractionSource = remember { MutableInteractionSource() } val pageIsPressed by pageInteractionSource.collectIsPressedAsState() // Stop auto-advancing when pager is dragged or one of the pages is pressed val autoAdvance = !pagerIsDragged && !pageIsPressed if (autoAdvance) { LaunchedEffect(pagerState, pageInteractionSource) { while (true) { delay(2000) val nextPage = (pagerState.currentPage + 1) % pageItems.size pagerState.animateScrollToPage(nextPage) } } } HorizontalPager( state = pagerState ) { page -> Text( text = "Page: $page", textAlign = TextAlign.Center, modifier = modifier .fillMaxSize() .background(pageItems[page]) .clickable( interactionSource = pageInteractionSource, indication = LocalIndication.current ) { // Handle page click } .wrapContentSize(align = Alignment.Center) ) } PagerIndicator(pageItems.size, pagerState.currentPage) } }
Kodla ilgili önemli noktalar
AutoAdvancePagerişlevi, otomatik ilerleme özelliğine sahip yatay sayfalama görünümü oluşturur. Giriş olarak, her sayfanın arka plan rengi olarak kullanılanColornesnelerinin listesini alır.pagerState, sayfa gezgininin durumunu tutanrememberPagerStatekullanılarak oluşturulur.pagerIsDraggedvepageIsPressed, kullanıcı etkileşimini izler.LaunchedEffect, kullanıcı sayfa gezginini sürüklemediği veya sayfalardan birine basmadığı sürece sayfa gezginini her iki saniyede bir otomatik olarak ilerletir.HorizontalPager, her biri sayfa numarasını gösteren birTextcomposable'ı içeren sayfaların listesini gösterir. Değiştirici, sayfayı doldurur, arka plan renginipageItemsolarak ayarlar ve sayfayı tıklanabilir hale getirir.
@Composable fun PagerIndicator(pageCount: Int, currentPageIndex: Int, modifier: Modifier = Modifier) { Box(modifier = Modifier.fillMaxSize()) { Row( modifier = Modifier .wrapContentHeight() .fillMaxWidth() .align(Alignment.BottomCenter) .padding(bottom = 8.dp), horizontalArrangement = Arrangement.Center ) { repeat(pageCount) { iteration -> val color = if (currentPageIndex == iteration) Color.DarkGray else Color.LightGray Box( modifier = modifier .padding(2.dp) .clip(CircleShape) .background(color) .size(16.dp) ) } } } }
Kodla ilgili önemli noktalar
Boxcomposable, kök öğe görevi görür ve sayfa göstergelerini yatay olarak düzenlemek için birRowiçerir.- Özel sayfa göstergesi, her bir
Boxöğesinin birCircleShapeile kırpılarak bir sayfayı temsil ettiği bir daire satırı olarak gösterilir. - Geçerli sayfanın dairesi
DarkGrayrenkte, diğer daireler iseLightGrayrenktedir.currentPageIndexparametresi, hangi dairenin koyu gri renkte oluşturulacağını belirler.
Sonuç
Bu videoda, önceki snippet'lerde yer alan temel otomatik ilerleyen sayfa gezgini gösterilmektedir: