如要左右或上下翻頁瀏覽內容,您可以分別使用 HorizontalPager
和 VerticalPager
可組合項。這些可組合項的功能與 View 系統中的 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() ) }
延遲建立
HorizontalPager
和 VerticalPager
的頁面都是延遲撰寫,並視需要排版。當使用者捲動頁面時,可組合項會移除不再需要的任何頁面。
載入更多畫面外網頁
根據預設,分頁器只會載入畫面上顯示的頁面。如要載入更多畫面外的網頁,請將 beyondBoundsPageCount
設為大於零的值。
捲動至分頁器中的項目
如要捲動至頁面器中的特定頁面,請使用 rememberPagerState()
建立 PagerState
物件,並將其做為 state
參數傳遞至呼叫器。您可以在 CoroutineScope
中呼叫此狀態的 PagerState#scrollToPage()
:
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
有三個屬性,可提供網頁資訊: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
。接著,您可以根據與所選頁面之間的距離,為內容套用轉換效果。
舉例來說,如要根據項目與中心的距離調整項目的不透明度,請在分頁器內的項目上使用 Modifier.graphicsLayer
變更 alpha
:
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
會設定一次可透過揮動手勢捲動的頁面數量上限。如要變更這項設定,請在 flingBehavior
上設定 pagerSnapDistance
:
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 關閉時顯示連結文字
- Compose 中的 ConstraintLayout
- 圖形修飾符
- 將
CoordinatorLayout
遷移至 Compose