안드로이드 앱의 메뉴 아이템에 Lottie Json을 사용 및 이벤트 처리하는 방식을 소개한다.
LottieImageView를 통해 사용하는 방법은 자료들이 꽤 있었지만, 나처럼 앱바에서 Lottie를 사용하는 예제는 많지 않은 것 같아서 글을 써본다!
이 글에 사용된 방법은 Lottie 5.2.0 버전에서 구현한 방법이다.
최신버전의 Lottie는 Lottie Github에서 확인할 수 있다.
https://github.com/airbnb/lottie-android
많은 앱들을 보면 아래의 사진 처럼 앱바의 메뉴를 통해 좋아요 또는 북마크 기능 등을 사용할 수 있는데, 나는 여기에 사용될 이미지에 lottie를 통해 애니메이션 기능을 구현하려고 한다.
먼저 내가 사용할 lottieFile을 아래의 링크에서 찾아서 json 형태로 저장해두자.
원하는 파일을 찾았다면 project > App 오른쪽마우스 클릭 > New > Folder > Assets Folder를 선택하여 에셋 폴더를 만들어준다. 이후 다운로드한 lottie json 파일을 에셋 경로에 넣어준다.
다음으로, 사용될 메뉴 아이템을 먼저 정의해주자.
res 폴더의 menu 디렉토리에 새로운 menu resource를 생성해주자. 나는 menu_details.xml 이라는 이름으로 정의해줬다.
이후 메뉴 아이템을 원하는 갯수만큼 생성해주자. 나는 좋아요, 북마크 두가지 기능이 필요했기 때문에 두개를 생성해 줬다.
<?xml version="1.0" encoding="utf-8"?>
<menu 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">
<item
android:enabled="true"
app:showAsAction="always"
tools:ignore="MenuTitle" />
<item
android:enabled="true"
app:showAsAction="always"
tools:ignore="MenuTitle" />
</menu>
여기에 정의된 메뉴에는 접근 가능한 id는 구현에 굳이 필요하지 않다.
이후 해당 메뉴를 사용 할 액티비티로 이동하여 아래의 코드를 추가한다.
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
menuInflater.inflate(R.menu.menu_detail, menu)
return super.onCreateOptionsMenu(menu)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
return super.onOptionsItemSelected(item)
}
보통은 onOptionsItemSelected 함수에서 menuItem의 Id로 접근하여 이벤트를 처리하겠지만, 이 예제에서는 onCreateOptionsMenu 함수에서 모든 일을 처리 할 것이다.
이후 onCreateOptionsMenu함수에서 아래의 코드를 작성한다.
val likeDrawable = LottieDrawable()
val bookMarkDrawable = LottieDrawable()
LottieCompositionFactory.fromAsset(this, "bookmark.json").addListener { result ->
bookMarkDrawable.composition = result
val item = menu?.getItem(0)
item?.icon = bookMarkDrawable
item?.setOnMenuItemClickListener {
if (!viewModel.isBookMarked.value!!) {
val animator = ValueAnimator.ofFloat(0f, 1f).setDuration(500)
animator.addUpdateListener {
bookMarkDrawable.progress = it.animatedValue as Float
}
animator.start()
viewModel.isBookMarked.value = true
} else {
val animator = ValueAnimator.ofFloat(1f, 0f).setDuration(500)
animator.addUpdateListener {
bookMarkDrawable.progress = it.animatedValue as Float
}
animator.start()
viewModel.isBookMarked.value = false
}
false
}
}
LottieCompositionFactory.fromAsset(this, "heart.json").addListener { result ->
likeDrawable.composition = result
val item = menu?.getItem(1)
item?.icon = likeDrawable
item?.setOnMenuItemClickListener {
if (!viewModel.isLiked.value!!) {
val animator = ValueAnimator.ofFloat(0f, 0.5f).setDuration(500)
animator.addUpdateListener {
likeDrawable.progress = it.animatedValue as Float
}
animator.start()
viewModel.isLiked.value = true
} else {
val animator = ValueAnimator.ofFloat(0.5f, 1f).setDuration(500)
animator.addUpdateListener {
likeDrawable.progress = it.animatedValue as Float
}
animator.start()
viewModel.isLiked.value = false
}
false
}
}
아래 처럼 잘 동작하는걸 확인할 수 있다!
'Android' 카테고리의 다른 글
Flow 재요청 버튼 활용하기 (0) | 2023.07.11 |
---|---|
A problem occurred configuring root project 'Unscramble'.> Could not resolve all files for configuration ':classpath'. 오류해결 (0) | 2023.06.08 |
kotlin data class redeclaration error 해결하기 (0) | 2022.12.10 |
manifestPlaceholders가 값을 찾지 못할 때 해결방법 (0) | 2022.11.27 |
Error inflating class com.google.android.material.bottomnavigation.BottomNavigationView (0) | 2022.11.13 |