728x90
Android 앱 개발을 Compose 로 구현하는데, 디자이너분께서 아래와 같은 Scroll Indicator 를 그려달라고 한다. (구현 예제화면)

스크롤의 움직임이 개발 마감기한과 완성도 사이에서 왔다갔다하는 내 신세를 보여주는 것 같아서 한번 구현해보기로 한다...ㅠ
개념부터 보자면
1. 리스트의 전체 카운트가 스크롤할 수 있는 최대 길이가 된다.
2. 현재 화면에 노출되는 마지막 아이템의 index가 현재 스크롤의 위치가 된다. 위와 같은 스크롤에서는 현재 스크롤이 몇 % 되었냐를 구하는 것이기 때문에 (현재 index / total count) 로 계산하였는데, 다른 스크롤처럼 보여줄 필요가 있을 때 이 부분을 응용해서 사용할 수 있겠다.
3. 스크롤 할 때, 현재 보이는 마지막 아이템의 index가 변화하는데 이걸 animation으로 나타내준다.
코드는 그렇게 어렵지 않다.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import androidx.compose.animation.core.animateDpAsState | |
import androidx.compose.foundation.background | |
import androidx.compose.foundation.layout.Box | |
import androidx.compose.foundation.layout.fillMaxWidth | |
import androidx.compose.foundation.layout.height | |
import androidx.compose.foundation.layout.width | |
import androidx.compose.foundation.lazy.LazyListState | |
import androidx.compose.foundation.shape.RoundedCornerShape | |
import androidx.compose.runtime.Composable | |
import androidx.compose.runtime.derivedStateOf | |
import androidx.compose.runtime.getValue | |
import androidx.compose.runtime.remember | |
import androidx.compose.ui.Alignment | |
import androidx.compose.ui.Modifier | |
import androidx.compose.ui.draw.clip | |
import androidx.compose.ui.graphics.Color | |
import androidx.compose.ui.unit.dp | |
@Composable | |
fun HorizontalSmallScrollIndicator( | |
modifier: Modifier = Modifier, | |
lazyRowState: LazyListState | |
) { | |
val layoutInfo = | |
remember { derivedStateOf { lazyRowState.layoutInfo } } | |
val totalItems = layoutInfo.value.totalItemsCount | |
val lastVisibleItemIndex = | |
layoutInfo.value.visibleItemsInfo.lastOrNull()?.index ?: 0 | |
val scrollFraction = | |
(lastVisibleItemIndex + 1).toFloat() / totalItems | |
val animatedWidth by animateDpAsState( | |
targetValue = 80.dp * scrollFraction, | |
label = "scrollIndicator" | |
) | |
Box( | |
modifier = modifier.fillMaxWidth(), | |
contentAlignment = Alignment.Center | |
) { | |
Box( | |
modifier = modifier | |
.width(80.dp) | |
.height(2.dp) | |
.clip(shape = RoundedCornerShape(16.dp)) | |
.background(Color.LightGray) | |
) { | |
Box( | |
modifier = modifier | |
.height(2.dp) | |
.width(animatedWidth) | |
.clip(shape = RoundedCornerShape(16.dp)) | |
.background(Color.DarkGray) | |
) | |
} | |
} | |
} |
간단하게 스크롤 인디케이터를 만들어봤다.
인디케이터의 크기나 작동 메커니즘 같은건 이 개념에서 응용해서 작성할 수 있을 것 같다.
마감기한을 잘 준수하면서 요구사항도 만족시켜서 다행이다!
끝!
728x90
'개발 > 안드로이드' 카테고리의 다른 글
위젯 만들기 (w/ Glance) (1) | 2024.08.06 |
---|---|
안드로이드 4대 컴포넌트 (0) | 2020.06.30 |
안드로이드, 플랫폼, 액티비티 - Android, Platform, Activity (0) | 2020.06.05 |
지도 API 비교(구글, 네이버, 카카오) (0) | 2020.05.06 |
댓글