2025.02.07 - [분류 전체보기] - Jetpack Compose에서 FlingBehavior로 부드러운 스크롤 제어하기
이전에 작성했던 글 대비
애니메이션 기반 스크롤도 확인 해볼까요

Jetpack Compose에서 스크롤 동작은 기본적으로 제공되지만, 사용자 경험(UX)을 개선하기 위해 부드러운 스크롤 플링(Fling)을 커스터마이징해야 할 때가 있습니다. 특히, 감속(deceleration)을 적절하게 설정하거나 애니메이션을 적용하면 더 자연스럽고 매끄러운 스크롤 경험을 제공할 수 있습니다. 본 가이드에서는 Jetpack Compose에서 부드러운 스크롤 플링을 구현하는 방법과 핵심적인 개념을 설명합니다.
1. 스크롤 플링(Fling)이란?
스크롤 플링(Fling)은 사용자가 스크롤을 끝내고 손가락을 떼었을 때 화면이 관성에 의해 움직이는 상태입니다.
- 감속이 중요: 적절한 감속 값을 설정하여 스크롤이 부드럽게 멈추도록 해야 합니다.
- 기본 FlingBehavior: Jetpack Compose는 기본적으로 DefaultFlingBehavior를 사용해 감속 동작을 제공합니다.
2. FlingBehavior를 활용한 부드러운 스크롤 구현
🔹 기본 FlingBehavior 적용 예제
import androidx.compose.foundation.gestures.DefaultFlingBehavior
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
@Composable
fun LazyColumnWithDefaultFling() {
val listState = rememberLazyListState()
val flingBehavior = DefaultFlingBehavior() // 기본 FlingBehavior 사용
LazyColumn(
state = listState,
flingBehavior = flingBehavior, // Fling 적용
modifier = Modifier.fillMaxSize()
) {
items(50) { index ->
Text(text = "Item $index")
}
}
}
설명
- DefaultFlingBehavior()를 통해 기본 감속 동작을 설정합니다.
- rememberLazyListState()를 사용해 스크롤 상태를 관리합니다.
3. 커스텀 FlingBehavior로 감속 제어
🔹 커스텀 감속 구현 예제
import androidx.compose.foundation.gestures.FlingBehavior
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import kotlinx.coroutines.yield
class CustomFlingBehavior : FlingBehavior {
override suspend fun ScrollScope.performFling(initialVelocity: Float): Float {
var velocity = initialVelocity
while (velocity > 1f) {
scrollBy(velocity * 0.05f) // 스크롤 거리
velocity *= 0.90f // 감속 비율 설정
yield() // 코루틴
}
return 0f
}
}
@Composable
fun LazyColumnWithCustomFling() {
val listState = rememberLazyListState()
val customFlingBehavior = CustomFlingBehavior()
LazyColumn(
state = listState,
flingBehavior = customFlingBehavior,
modifier = Modifier.fillMaxSize()
) {
items(50) { index ->
Text(text = "Item $index")
}
}
}
설명
- velocity *= 0.90f: 감속 비율을 설정합니다. 감속 값을 높이면 스크롤이 더 느리게 멈춥니다.
- yield(): 코루틴이 다른 작업에 CPU 자원을 양보하도록 설정합니다.
4. 애니메이션 기반 스크롤로 더욱 부드러운 효과 구현
Jetpack Compose는 스프링 애니메이션(Spring Animation)을 활용해 더욱 부드러운 스크롤 효과를 구현할 수 있습니다.
🔹 Spring Animation을 활용한 스크롤 제어 예제
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import kotlinx.coroutines.delay
import androidx.compose.animation.core.spring
import androidx.compose.animation.core.Spring
@Composable
fun SmoothAnimatedScroll() {
val scrollState = rememberScrollState()
LaunchedEffect(Unit) {
scrollState.animateScrollTo(
targetValue = 1000, // 스크롤 목표 위치
animationSpec = spring(
dampingRatio = Spring.DampingRatioMediumBouncy,
stiffness = Spring.StiffnessLow
)
)
}
Column(modifier = Modifier.verticalScroll(scrollState)) {
repeat(50) { index ->
Text(text = "Item $index")
}
}
}
설명
- dampingRatio: 스크롤 탄성 효과의 정도를 조정합니다.
- stiffness: 스크롤 속도의 강도를 설정합니다.
- Spring 애니메이션은 Fling보다 더욱 부드러운 스크롤 효과를 제공합니다.
5. Column에서 부드러운 스크롤 플링 제어하기
Column은 LazyColumn과 달리 기본적으로 스크롤이나 플링 동작을 지원하지 않습니다. 이를 해결하기 위해 verticalScroll()로 스크롤 동작을 추가해야 합니다.
🔹 Column에 스크롤 동작 추가 예제
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
@Composable
fun ColumnWithSmoothScroll() {
val scrollState = rememberScrollState()
Column(
modifier = Modifier
.verticalScroll(scrollState)
.fillMaxSize()
) {
repeat(50) { index ->
Text(text = "Item $index")
}
}
}
6. LazyColumn과 Column 비교
항목 LazyColumn Column
스크롤 지원 | 기본 지원 | verticalScroll() 필요 |
Fling 제어 | FlingBehavior 지원 | 미지원 |
효율성 | 대용량 데이터 최적화 | 모든 데이터 로드 |
7. 자주 묻는 질문 (FAQ)
Q1. Fling 속도를 더 부드럽게 조정하려면 어떻게 해야 하나요?
CustomFlingBehavior에서 감속 값을 velocity *= 0.95f로 설정하면 스크롤이 더 부드럽게 멈춥니다.
Q2. LazyColumn과 Column 중 어떤 것을 선택해야 하나요?
대용량 데이터에 최적화된 LazyColumn을 권장합니다. 하지만 간단한 레이아웃에서는 Column도 적절합니다.
Q3. 스프링 애니메이션이 Fling보다 나은가요?
Fling은 관성 기반 스크롤에 적합하고, 스프링 애니메이션은 자연스러운 애니메이션 효과를 제공하므로 상황에 따라 선택합니다.
결론
Jetpack Compose에서 FlingBehavior와 스프링 애니메이션을 활용하여 더욱 부드럽고 매끄러운 스크롤 경험을 제공할 수 있습니다. LazyColumn은 Fling 제어에 적합하며, Column은 스크롤이 필요한 단순 레이아웃에 적합합니다.