새로고침을 위한 드래그 구성요소를 사용하면 사용자가 앱 콘텐츠 시작 부분에서 아래로 드래그하여 데이터를 새로고침할 수 있습니다.
API 노출 영역
PullToRefreshBox 컴포저블을 사용하여 스크롤 가능한 콘텐츠의 컨테이너 역할을 하는 새로고침을 구현합니다. 다음 주요 매개변수는 새로고침 동작과 모양을 제어합니다.
isRefreshing: 새로고침 작업이 진행 중인지 여부를 나타내는 불리언 값입니다.onRefresh: 사용자가 새로고침을 시작할 때 실행되는 람다 함수입니다.indicator: 시스템이 새로고침을 위해 당기기에 그리는 표시기를 맞춤설정합니다.
기본 예
이 스니펫은 PullToRefreshBox의 기본 사용법을 보여줍니다.
@Composable fun PullToRefreshBasicSample( items: List<String>, isRefreshing: Boolean, onRefresh: () -> Unit, modifier: Modifier = Modifier ) { PullToRefreshBox( isRefreshing = isRefreshing, onRefresh = onRefresh, modifier = modifier ) { LazyColumn(Modifier.fillMaxSize()) { items(items) { ListItem({ Text(text = it) }) } } } }
코드에 관한 핵심 사항
PullToRefreshBox은 문자열 목록을 표시하는LazyColumn을 래핑합니다.PullToRefreshBox에는isRefreshing및onRefresh매개변수가 필요합니다.PullToRefreshBox블록 내의 콘텐츠는 스크롤 가능한 콘텐츠를 나타냅니다.
결과
이 동영상에서는 앞의 코드에서 기본 새로고침 구현을 보여줍니다.
고급 예: 표시기 색상 맞춤설정
@Composable fun PullToRefreshCustomStyleSample( items: List<String>, isRefreshing: Boolean, onRefresh: () -> Unit, modifier: Modifier = Modifier ) { val state = rememberPullToRefreshState() PullToRefreshBox( isRefreshing = isRefreshing, onRefresh = onRefresh, modifier = modifier, state = state, indicator = { Indicator( modifier = Modifier.align(Alignment.TopCenter), isRefreshing = isRefreshing, containerColor = MaterialTheme.colorScheme.primaryContainer, color = MaterialTheme.colorScheme.onPrimaryContainer, state = state ) }, ) { LazyColumn(Modifier.fillMaxSize()) { items(items) { ListItem({ Text(text = it) }) } } } }
코드에 관한 핵심 사항
- 표시기의 색상은
indicator매개변수의containerColor및color속성을 통해 맞춤설정됩니다. rememberPullToRefreshState()은 새로고침 작업의 상태를 관리합니다. 이 상태는indicator매개변수와 함께 사용됩니다.
결과
이 동영상은 색상이 지정된 표시기가 있는 새로고침 구현을 보여줍니다.
고급 예: 완전히 맞춤설정된 표시기 만들기
기존 컴포저블과 애니메이션을 활용하여 복잡한 맞춤 표시기를 만들 수 있습니다. 이 스니펫은 새로고침 구현에서 완전히 맞춤설정된 표시기를 만드는 방법을 보여줍니다.
@Composable fun PullToRefreshCustomIndicatorSample( items: List<String>, isRefreshing: Boolean, onRefresh: () -> Unit, modifier: Modifier = Modifier ) { val state = rememberPullToRefreshState() PullToRefreshBox( isRefreshing = isRefreshing, onRefresh = onRefresh, modifier = modifier, state = state, indicator = { MyCustomIndicator( state = state, isRefreshing = isRefreshing, modifier = Modifier.align(Alignment.TopCenter) ) } ) { LazyColumn(Modifier.fillMaxSize()) { items(items) { ListItem({ Text(text = it) }) } } } } // ... @Composable fun MyCustomIndicator( state: PullToRefreshState, isRefreshing: Boolean, modifier: Modifier = Modifier, ) { Box( modifier = modifier.pullToRefresh( state = state, isRefreshing = isRefreshing, threshold = PositionalThreshold, onRefresh = { } ), contentAlignment = Alignment.Center ) { Crossfade( targetState = isRefreshing, animationSpec = tween(durationMillis = CROSSFADE_DURATION_MILLIS), modifier = Modifier.align(Alignment.Center) ) { refreshing -> if (refreshing) { CircularProgressIndicator(Modifier.size(SPINNER_SIZE)) } else { val distanceFraction = { state.distanceFraction.coerceIn(0f, 1f) } Icon( imageVector = Icons.Filled.CloudDownload, contentDescription = "Refresh", modifier = Modifier .size(18.dp) .graphicsLayer { val progress = distanceFraction() this.alpha = progress this.scaleX = progress this.scaleY = progress } ) } } } }
코드에 관한 핵심 사항
- 이전 스니펫에서는 라이브러리에서 제공하는
Indicator를 사용했습니다. 이 스니펫은MyCustomIndicator라는 맞춤 표시기 컴포저블을 만듭니다. 이 컴포저블에서pullToRefreshIndicator수정자는 위치 지정과 새로고침 트리거를 처리합니다. - 이전 스니펫과 마찬가지로 이 예에서는
PullToRefreshState인스턴스를 추출하므로PullToRefreshBox과pullToRefreshModifier모두에 동일한 인스턴스를 전달할 수 있습니다. - 이 예시에서는
PullToRefreshDefaults클래스의 컨테이너 색상과 위치 임계값을 사용합니다. 이렇게 하면 Material 라이브러리의 기본 동작과 스타일을 재사용하면서 관심 있는 요소만 맞춤설정할 수 있습니다. MyCustomIndicator는Crossfade를 사용하여 클라우드 아이콘과CircularProgressIndicator간에 전환합니다. 사용자가 당기면 클라우드 아이콘이 확대되고 새로고침 작업이 시작되면CircularProgressIndicator로 전환됩니다.targetState는isRefreshing를 사용하여 표시할 상태 (클라우드 아이콘 또는 원형 진행 상태 표시기)를 결정합니다.animationSpec는 전환을 위한tween애니메이션을 정의하며, 지정된 재생 시간은CROSSFADE_DURATION_MILLIS입니다.state.distanceFraction는 사용자가 아래로 당긴 거리를 나타내며,0f(당기지 않음)에서1f(완전히 당김)까지의 범위를 갖습니다.graphicsLayer수정자는 크기와 투명도를 수정합니다.
결과
이 동영상에서는 앞의 코드에 나온 맞춤 표시기를 보여줍니다.