콘텐츠를 좌우 또는 위아래로 넘기려면
HorizontalPager
및
VerticalPager
구성 가능한 함수를 각각 만들 수 있습니다. 이러한 컴포저블은 뷰 시스템의 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
를 0보다 큰 값으로 설정합니다.
호출기에서 항목으로 스크롤
페이저에서 특정 페이지로 스크롤하려면 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
가 즉시 업데이트되지만settledPage
는 모든 애니메이션이 실행 완료될 때까지 동일하게 유지된다는 점에서currentPage
속성과 다릅니다.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
객체를 만들고 1의 간격을 고려하여 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
는
플링 동작이 한 번에 한 페이지까지 스크롤할 수 있는 페이지입니다. 변경하려면
설정
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), beyondViewportPageCount = 10, flingBehavior = fling ) { PagerSampleItem(page = it) } }
추천 서비스
- 참고: JavaScript가 사용 중지되어 있으면 링크 텍스트가 표시됩니다.
- Compose의 ConstraintLayout
- 그래픽 수정자
CoordinatorLayout
를 Compose로 이전