Lottie
는 JSON
기반의 정적인 자산을 사용하여 Android, iOS, Web, React Native, Windows
와 같이 다양한 플랫폼에 사용되며
애니메이션을 배치할 수 있는 애니메이션 파일
이다.
gjf
, mp4
를 사용하지 않고, JSON
을 사용하여 애니메이션을 표현할 수 있는 특징이 있다.
LottieFiles - What is a Lottie? 글을 참조하였다.
우리는 상용되어있는 여러 SNS 앱을 사용하면서 Like 또는 '좋아요'를 눌러본 경험이 있을 것이다.
ex) Instagram, facebook, twitter ...
다음과 같은 애니메이션 효과들이 모두 Lottie Animation
의 예시라고 할 수 있다.
이러한 애니메이션 효과가 사용되는 App을 사용한다면 사용자들은 어떤 느낌을 받을까 ?
일단 직관적인 느낌을 받을 것이다.
사용자의 Action을 한 번 더 강조해주고, 직접 사용자와 상호작용하는 느낌을 줄 것이다.
Lottie Animation
은 High Quality의 Animation 효과를 다양한 플랫폼에서 사용할 수 있는 Animation 라이브러리이다.
이 라이브러리를 예제를 통해 접해보고자 한다.
dependencies {
implementation 'com.airbnb.android:lottie:$lottieVersion'
}
공식 문서를 보면 build.gradle
파일에 다음과 같이 gradle을 추가하라고 설명한다.
build.gradle
파일에서 값을 저장하는 변수를 사용하려면 def
을 통해 선언할 수 있다.
$
를 사용하여 변수 값을 즉시 가져올 수 있다. 하지만 ""
(Double Quotation) 안에서만 사용할 수 있다.
현재 작성일 기준 최신 버전이 5.2.0이므로 다음과 같이 gradle을 추가해준다.
LottieFiles링크로 이동하여 원하는 애니메이션을 선택 후,
Download
- Lottie JSON
을 선택하면 JSON 파일이 다운로드가 된다.
LottieFiles - Heart 를 사용하기로 결정하였다.
다운로드를 마쳤다면, 다음과 같은 과정을 통해 생성된 assets
디렉터리에 다운로드받은 heart.json
애니메이션 JSON 파일을 넣는다.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
tools:context=".MainActivity">
<com.airbnb.lottie.LottieAnimationView
android:id="@+id/like_btn"
android:layout_width="300dp"
android:layout_height="300dp"
android:background="@color/white"
app:lottie_fileName="heart.json"
app:lottie_autoPlay="false"
app:lottie_loop="false"
android:layout_centerInParent="true"
/>
</RelativeLayout>
RelativeLayout
을 사용하며, android:layout_centerInParent="true"
를 통해 LottieAnimationView
를 부모의 가운데로 위치시켰다.
LottieAnimationView
의 id
값을 like_btn
으로 하였다. ClickListener
를 사용하여 '좋아요' 버튼 처럼 사용해 볼 에정이다.
app:lottie_fileName="file_name"
파일 이름을 통해 LottieAnimationView
에 보여질 애니메이션을 정하는 설정 값이다.
app:lottie_autoPlay="true" or false
를 통해서 애니메이션이 자동으로 초기에 재생이 되는 지 설정할 수 있다.
true
인 경우, 화면이 보이자마자 애니메이션이 재생된다.
app:lottie_loop="true or false"
를 통해 반복되어 애니메이션이 재생되는 지를 설정할 수 있다. true
이면 애니메이션이 계속 재생이 된다.
app:lottie_url="url"
을 통해 url 값을 전달하여 보여질 애니메이션을 불러올 수 있다.
app:lottie_repeatCount = "반복횟수값"
를 통해 애니메이션이 반복 재생 될 횟수를 지정할 수 있다.
playAnimation()
메서드를 통해 애니메이션을 재생할 수 있다.
class MainActivity : AppCompatActivity() {
private val TAG : String = "로그"
private lateinit var like_btn : LottieAnimationView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
like_btn = findViewById<LottieAnimationView>( R.id.like_btn )
like_btn.setOnClickListener {
onLikeBtnClicked()
}
}
fun onLikeBtnClicked() {
Log.d(TAG,"MainActivity - onLikeBtnClicked() called / 좋아요 버튼이 클릭되었다.")
// LottieAnimationView.playAnimation() => Animation 을 재생한다.
like_btn.playAnimation()
}
}
Customizing
을 통해 우리가 재생하고자 하는 애니메이션을 자유자재로 다룰 수도 있다.
ClickListener
를 사용하여 LottieAnimationView
(좋아요 버튼)을 클릭하면 하트에 불이 들어오게
, 다시 한 번 더 클릭하면 하트에 불이 꺼지게 해보자.
하지만 우리가 다운로드 받은 애니메이션을 재생하면 하트에 불이 들어왔다 자동으로 다시 꺼진다.
이 목표를 달성하기 위해 어떻게 하는게 좋을까 ? 공식문서를 참조하여
Customizing
해보자.
다음과 같은 코드를 통해, 우리가 다운로드 받은 애니메이션의 재생구간
, 지속시간
을 Custom 할 수 있다고 한다. 이를 적용해보자.
// Custom animation speed or duration.
val animationView = findViewById<LottieAnimationView>( R.id.animationView )
val animator = ValueAnimator.ofFloat(0f, 1f)
animator.addUpdateListener { animation : ValueAnimator ->
animationView.setProgress(animation.animatedValue)
}
animator.start()
최종으로 좋아요
와 좋아요 취소
기능이 구현이 완료된LottieAnimationView
에 대해 Custom 동작을 한 샘플코드이다.
class MainActivity : AppCompatActivity() {
private val TAG : String = "로그"
private lateinit var like_btn : LottieAnimationView
private var isLiked : Boolean = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
like_btn = findViewById<LottieAnimationView>( R.id.like_btn )
like_btn.setOnClickListener {
onLikeBtnClicked()
}
}
fun onLikeBtnClicked() {
Log.d(TAG,"MainActivity - onLikeBtnClicked() called / 좋아요 버튼이 클릭되었다. isLiked : $isLiked")
// 애니메이션의 커스텀
// Custom animation speed or duration
// ofFloat(시작지점, 종료지점).setDuration(지속시간 ms)
// 최소시작지점은 0f이며
// 종료지점은 1f로 구분한다.
lateinit var animator : ValueAnimator
if( !isLiked ) { // 아직 좋아요 버튼을 누르지 않았을 때
animator = ValueAnimator.ofFloat(0f, 0.5f)
isLiked = true
} else { // 이미 좋아요 버튼이 눌려있는 상태일 때
animator = ValueAnimator.ofFloat(0.5f, 1f)
isLiked = false
}
animator.addUpdateListener { animation : ValueAnimator ->
like_btn.setProgress(animation.animatedValue as Float)
}
animator.start()
// 0 ~ 1 까지 모두 재생
// LottieAnimationView.playAnimation() => Animation 을 재생한다.
// like_btn.playAnimation()
}
}
좋아요
를 실행하고 취소하는 부분인 onLikeBtnClicked()
를 주로 보겠다.
fun onLikeBtnClicked() {
Log.d(TAG,"MainActivity - onLikeBtnClicked() called / 좋아요 버튼이 클릭되었다. isLiked : $isLiked")
// 애니메이션의 커스텀
// Custom animation speed or duration
// ofFloat(시작지점, 종료지점).setDuration(지속시간 ms)
// 최소시작지점은 0f이며
// 종료지점은 1f로 구분한다.
lateinit var animator : ValueAnimator
if( !isLiked ) { // 아직 좋아요 버튼을 누르지 않았을 때
animator = ValueAnimator.ofFloat(0f, 0.5f)
isLiked = true
} else { // 이미 좋아요 버튼이 눌려있는 상태일 때
animator = ValueAnimator.ofFloat(0.5f, 1f)
isLiked = false
}
animator.addUpdateListener { animation : ValueAnimator ->
like_btn.setProgress(animation.animatedValue as Float)
}
animator.start()
// 0 ~ 1 까지 모두 재생
// LottieAnimationView.playAnimation() => Animation 을 재생한다.
// like_btn.playAnimation()
}
LottieAnimationView().playAnimation()
을 통해 애니메이션을 재생할 수 있다.
하지만, 이 코드의 경우, 애니메이션을 최초 시작(0f)부터 마지막 종료(1f)까지 다 재생하므로 우리가 달성하고자 하는 목표를 만족하지 못한다.
위에서 Customizing 을 하는 방법에 대해서 살펴보았다.
// Custom animation speed or duration.
val animationView = findViewById<LottieAnimationView>( R.id.animationView )
val animator = ValueAnimator.ofFloat(0f, 1f)
animator.addUpdateListener { animation : ValueAnimator ->
animationView.setProgress(animation.animatedValue)
}
animator.start()
ofFloat(시작지점(float), 종료지점(float))
- 애니메이션의 재생 구간을 설정한다.
애니메이션이 최초로 시작되는 지점
은 0f ,마지막으로 재생을 완전히 종료하는 지점
은 1f 이다.
setDuration(지속할ms)
- 위와 같이 설정된 구간의 애니메이션이 재생이 된 후, 지속될 시간을 설정한다.
private var isLiked : Boolean = false
isLiked
= 현재 '좋아요'상태를 체크하기 위한 Boolean
형 변수이다.
초기 값을 false
로 하였으며, '좋아요'가 되어있지 않은 상태를 의미한다. true
라면 '좋아요'가 되어있는 상태이다.
onLikeBtnClicked()
가 실행되었을 때, isLiked
의 값에 따라(좋아요 여부에 따라) 실행되는 코드이다.
위 heart.json
파일의 경우, 대략적으로 0f ~ 0.5f
에서 하트가 채워지고, 0.5f ~ 1f
과정에서 하트가 비워진다.
onLikeBtnClicked()
의 내부 로직이다.
lateinit var animator : ValueAnimator
if( !isLiked ) { // 아직 좋아요 버튼을 누르지 않았을 때
animator = ValueAnimator.ofFloat(0f, 0.5f)
isLiked = true
} else { // 이미 좋아요 버튼이 눌려있는 상태일 때
animator = ValueAnimator.ofFloat(0.5f, 1f)
isLiked = false
}
animator.addUpdateListener { animation : ValueAnimator ->
like_btn.setProgress(animation.animatedValue as Float)
}
animator.start()
isLiked
의 값이 true
or false
에 따라 하트가 채워지고, 비워지는 animator
를 할당하여 재생을 하였고, isLiked
의 값을 갱신하는 로직이다.
처음으로 사용해본 라이브러리였다. 이렇게 애니메이션도 다룰 수 있구나 싶었다.
Lottie Animation
은 고(?)퀄리티의 애니메이션 작업을 위한 오픈소스 라이브러리라고 볼 수 있다.
처음으로 다루어 본 오픈소스 라이브러리는 아니지만, 역시나 오픈소스 라이브러리를 사용하는 것은 고된 일인 것 같다.
이전에도 이미지를 다룰 때 사용하는 Glide
그리고oAuth
를 다루는 Kakao Login API
, Naver Login API
, Google Login API
등 여러 오픈소스 라이브러리를 다뤄본 기억이 있다. (물론 기억은 잘 나지 않지만...)
이번 Lottie Animation
라이브러리가 블로그에서는 처음으로 오픈소스 라이브러리를 다룬 글이다.
앞으로 오픈소스 라이브러리들을 사용하는 경우가 많을 것이다.
이 글에 오픈소스 라이브러리에 대한 Tip을 정리하자면, 오픈소스 라이브러리를 사용할 땐, 오픈소스의 공식문서들을 참조하는 것이 가장 중요하다고 생각한다.
그 외 Lottie에 관한 기술 블로그 글