티스토리 뷰
👍 Lottie의 장점
Lottie는 gif와 비교해서 여러 장점이 있다.
1. 파일의 크기
git는 프레임마다 전체 이미지를 저장하는 비트맵 기반 포맷이다. 하지만 Lottie는 Json 기반으로 구현된 애니메이션 파일이기 때문에 gif 파일보다 낮은 용량을 사용하게 된다.
낮은 용량을 사용하는 것은 로딩 속도가 그만큼 빨라지기 때문에, 사용자 경험에 만족을 줄 수 있다.
앱의 크기 측면에서도 용량이 적기 때문에 이득이다.
2. 품질
gif 파일은 해상도가 정해져있는 파일이기 때문에, 크기에 따라 품질이 크게 깨진다. 만약 큰 화면에서 gif 파일을 보여주게 된다면 화면이 깨져 보일 것이다.
하지만 Lottie는 Json으로 되어있고 백터로 렌더링하기 때문에 해상도가 정해져있지 않다. 따라서 화질이 깨지지 않는다.
3. 동적 제어 가능
Lottie는 재생, 정지, 반복 횟수, 속도 등을 런타임에서 자유롭게 제어가 가능하다는 점에서 커스텀이 자유롭다.
XML
의존성 추가
앱단위 build.gradle 파일에 다음을 추가한다.
def lottieVersion = "5.2.0"
implementation "com.airbnb.android:lottie:$lottieVersion"
LottieAnimationView 추가
<com.airbnb.lottie.LottieAnimationView
android:id="@+id/lav_schedule_event_time_line_circle"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_marginStart="32dp"
android:layout_marginEnd="12dp"
android:contentDescription="@string/schedule_circle"
android:elevation="11dp"
app:layout_constraintBottom_toBottomOf="@id/cl_schedule_event_card"
app:layout_constraintEnd_toStartOf="@id/cl_schedule_event_card"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/cl_schedule_event_card"
app:lottie_autoPlay="true"
app:lottie_loop="true"
app:lottie_rawRes="@raw/pulse_circle"
app:timeLineCircleStatus="@{scheduleEvent.status}" />
lottie_autoPlay: 자동으로 gif 파일을 움직일지 정한다.
lottie_rawRes: json 파일 경로를 정해준다.
lottie_loop: 몇번 반복할지 정한다.
Kotlin
@BindingAdapter("timeLineCircleStatus")
fun setTimeLineCircle(
view: LottieAnimationView,
status: ScheduleEventUiStatus?,
) {
status ?: return
when (status) {
ScheduleEventUiStatus.UPCOMING -> {
val color = ContextCompat.getColor(view.context, R.color.green400)
view.addValueCallback(
KeyPath("centerCircle", "**", "Fill 1"),
LottieProperty.COLOR,
) { color }
view.addValueCallback(
KeyPath("outerWave", "**", "Fill 1"),
LottieProperty.OPACITY,
) { 0 }
view.addValueCallback(
KeyPath("innerWave", "**", "Fill 1"),
LottieProperty.OPACITY,
) { 0 }
}
ScheduleEventUiStatus.ONGOING -> {
val color = ContextCompat.getColor(view.context, R.color.blue400)
view.addValueCallback(
KeyPath("centerCircle", "**", "Fill 1"),
LottieProperty.COLOR,
) { color }
view.addValueCallback(
KeyPath("outerWave", "**", "Fill 1"),
LottieProperty.OPACITY,
) { 100 }
view.addValueCallback(
KeyPath("innerWave", "**", "Fill 1"),
LottieProperty.OPACITY,
) { 100 }
view.addValueCallback(
KeyPath("outerWave", "**", "Fill 1"),
LottieProperty.COLOR,
) { color }
view.addValueCallback(
KeyPath("innerWave", "**", "Fill 1"),
LottieProperty.COLOR,
) { color }
}
ScheduleEventUiStatus.COMPLETED -> {
val color = ContextCompat.getColor(view.context, R.color.gray300)
view.addValueCallback(
KeyPath("centerCircle", "**", "Fill 1"),
LottieProperty.COLOR,
) { color }
view.addValueCallback(
KeyPath("outerWave", "**", "Fill 1"),
LottieProperty.OPACITY,
) { 0 }
view.addValueCallback(
KeyPath("innerWave", "**", "Fill 1"),
LottieProperty.OPACITY,
) { 0 }
}
}
}
사용법
- LottieFiles에서 원하는 gif파일을 json 파일로 다운 받는다.
- res/raw 하단에 json 파일을 추가한다.
- 뷰바인딩, 바인딩 어댑터 등을 사용하여 상황에 맞는 원하는 형태로 커스텀한다.’
🚀 Jetpack Compose
의존성 추가
앱단위 build.gradle 파일에 다음을 추가한다.
implementation "com.airbnb.android:lottie-compose:$lottieVersion"
사용법
rememberLottieComposition
Lottie의 파일을 파싱해서 LottieComposition 객체로 만들어주는 역할을 한다.
val composition by rememberLottieComposition(LottieCompositionSpec.RawRes(R.raw.loading))
다음과 같이 by 키워드를 통해 사용할 수 있다.
rememberLottieComposition()의 반환타입은
interface LottieCompositionResult : State<LottieComposition?>
State타입을 반환하므로 by 위임을 통해 내부 값인 value를 직접 사용가능하다.
또한 remember 키워드가 붙어 있어서, 리컴포지션이 일어나도 이미 파싱한 LottieComposition을 사용한다. 현재 예제 코드에서는 res/raw에 있는 json파일을 재사용하는 것이다.
animateLottieCompositionAsState
애니메이션을 자동으로 움직여야할 때 필요하며, 재생, 반복, 정지, 진행률(progress)를 관리해주는 역할을 한다.
animateLottieCompositionAsState는 내부적으로 remember를 사용하고 있기 때문에, remember로 감싸주지 않아도 된다.
즉, 애니메이션을 조작하는 역할을 한다.
val progress by animateLottieCompositionAsState(
composition = composition,
iterations = LottieConstants.IterateForever,
)
LottieConstants.IterateForever는 무한 재생을 의미한다.
LottieAnimation
LottieAnimation(composition = composition, progress = { progress }, modifier = modifier)
LottieAnimation를 사용하여 화면에 애니메이션을 그린다.
🧑🏻💻 코드 예시
@Composable
fun LoadingScreen(modifier: Modifier = Modifier) {
val composition by rememberLottieComposition(LottieCompositionSpec.RawRes(R.raw.loading))
val progress by animateLottieCompositionAsState(
composition = composition,
iterations = LottieConstants.IterateForever,
)
LottieAnimation(
composition = composition,
progress = { progress },
modifier = modifier.fillMaxSize(),
)
}
둘 다 써보니까 컴포즈가 훨씬 덜 복잡하고 직관적인 느낌이다..
'안드로이드' 카테고리의 다른 글
| Hilt, Metro의 DI 그래프 생성, 등록, 주입 차이 (0) | 2025.12.08 |
|---|---|
| Metro로 ViewModel 생성하기 (0) | 2025.11.06 |
| LifeCycle Of ViewModel (1) | 2025.10.05 |
| Android Thread 통신과 Handler·Looper (4) | 2025.08.29 |
| DataBinding, BindingAdapter를 사용할 때 무한루프 (2) | 2025.08.02 |