관리 메뉴

막내의 막무가내 프로그래밍 & 일상

[안드로이드] Lottie Animation 사용법 본문

안드로이드/코틀린 & 아키텍처 & Recent

[안드로이드] Lottie Animation 사용법

막무가내막내 2020. 8. 2. 12:33
728x90

 

[2021-04-14 업데이트]

Lottie 최신 코드는 가장 하단에 PS 부분에 있으니 참고해주세요 :)

 

 

 

 

Lottie 사용법에 대해 간단하게 포스팅하는 시간을 가져 보겠습니다 ㅎㅎ

 

 

Lottie 란 위 설명대로 어떤 네이티브 앱에서든 쉽고 높은 퀄리티의 애니메이션을 구현할 수 있게한 라이브러리입니다.

로띠에 대한 설명과 장점은 다음 사이트에서 더 자세하게 볼 수 있습니다. 

https://airbnb.design/lottie/

 

Lottie

Easily add high-quality animation to any native app. Lottie is an iOS, Android, and React Native library that renders After Effects animations in real time, allowing apps to use animations as easily as they use static images.

airbnb.design

https://medium.com/@congjang/f-%EB%B2%88%EC%99%B8%ED%8E%B8-lottie%EB%A1%9C-animation-%EB%A7%8C%EB%93%A4%EA%B8%B0-93135f18e450

 

Lottie Animation 만들기(1)

Bodymovin plugin 과 after effect 로 JSON파일 추출하기

medium.com

 

 

사용법에 대해 살펴보겠습니다.

1. build.gradle 에 디펜던시를 추가해줍니다.

 implementation 'com.airbnb.android:lottie:3.0.7'

 

 

2. 자신이 원하는 Lottie 애니메이션을 다운받습니다.

전 아래 사이트에서 애니메이션을 다운받았습니다. Lottie Json 을 다운받아야합니다.

https://lottiefiles.com/28705-student-university-character

 

Student university character. on Lottiefiles. Free Lottie Animation

Student character with laptop drinking coffee while he study.Lottie animation made for: Arigato Studio.. Use on your web, react, flutter, xamarin iOS and Android projects and apps

lottiefiles.com

 

 

 

 

3.  Raw 리소스 폴더를 생성하고 다운받은 json 파일을 복사붙여넣기 해줍니다. asset 폴더로 하는 방법도 있는데 전 build를 해도 인식을 못하길래 이와 같은 방법으로 했습니다.

 

 

 

 

 

4. xml 을 구현합니다

autPLay는 자동 재생, loop는 무한반복할 것인지, rawRes 에는 Lottie Json 파일을 설정해주면 됩니다.

<com.airbnb.lottie.LottieAnimationView
                android:id="@+id/lottieView"
                android:layout_width="0dp"
                android:layout_height="100dp"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent"
                app:lottie_rawRes="@raw/loading_lottie"
                app:lottie_autoPlay="true"
                app:lottie_loop="true" />

 

이렇게 코드상에서 실행시켜줘도 됩니다.

lottie.playAnimation();
        lottie.loop(true);

 

 

5. 코드에서 리스너를 통해 조작할 수 도 있습니다

lottieView.addAnimatorListener(object : Animator.AnimatorListener {
            override fun onAnimationStart(animation: Animator) {
            }

            override fun onAnimationEnd(animation: Animator) {
            }

            override fun onAnimationCancel(animation: Animator) {
            }

            override fun onAnimationRepeat(animation: Animator) {
            }
        })

 

 

 

[결과]

 

 

[P.S]

Lottie 를 프로그래스바나 다이얼로그 프래그먼트처럼 사용하고싶다면 다음 사이트를 참고하시면 됩니다.

https://medium.com/@hasanshaikh/progress-bar-using-lottie-animation-android-6868b58878bf

 

Progress Bar Using Lottie Animation (Android)

Lottie is a mobile library for Android and iOS that parses Adobe After Effects animations exported as json with Bodymovin and renders them…

medium.com

https://hackernoon.com/how-to-create-awesome-loaders-on-android-with-lottie-animations-mr31327j

 

How to Create Awesome Loaders on Android with Lottie Animations | Hacker Noon

Most modern mobile apps carry out asynchronous operations, operations that would require the user to wait while the app is busy. Creating nice interactive loaders that match the purpose of your app will greatly improve the user experience in your app. For

hackernoon.com

 

[Example]

5초 동안 다이얼로그 프래그먼트 다이얼로그가 나오고 사라지는 로직 (다이얼로그에서는 클릭이벤트 Block)

 

[다이얼로그 프래그먼트]

package com.mtjin.worksdesign

import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.Window
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.FragmentManager


class LottieDialogFragment : DialogFragment() {


    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        dialog?.requestWindowFeature(Window.FEATURE_NO_TITLE)
        dialog?.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))

        isCancelable = false
        return inflater.inflate(R.layout.dialog_lottie, container, false)
    }

    override fun show(manager: FragmentManager, tag: String?) {
        try {
            val ft = manager.beginTransaction()
            ft.add(this, tag)
            ft.commitAllowingStateLoss()
        } catch (ignored: IllegalStateException) {

        }

    }
}

 

[xml]

<?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"
    android:layout_width="100dp"
    android:layout_height="100dp"
    android:orientation="vertical">

    <com.airbnb.lottie.LottieAnimationView
        android:id="@+id/progressAnimationView"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_centerInParent="true"
        app:lottie_autoPlay="true"
        app:lottie_loop="true"
        app:lottie_rawRes="@raw/loading_lottie" />
</RelativeLayout>

 

 

[show, hide]

private val loadingDialogFragment by lazy { LottieDialogFragment() }
private fun showProgressDialog() {
        if (!loadingDialogFragment.isAdded) {
            loadingDialogFragment.show(supportFragmentManager, "loader")
        }
    }

    private fun hideProgressDialog() {
        if (loadingDialogFragment.isAdded) {
            loadingDialogFragment.dismissAllowingStateLoss()
        }
    }

 

showProgressDialog()
val handler: Handler = Handler()
        handler.postDelayed({
            hideProgressDialog()
        },
        5000)

 

 

 

 


 

 

 

 

 

 

[2020-09-15 업데이트]

로띠 다이얼로그 프래그먼트를 싱글톤으로 업데이트하여 코드가 좀 변경되었습니다.

BaseFragment 와 BaseVIewModel 을 통해 다이얼로그프래그먼트를 띄우는 예제입니다.

 

[Fragment]

package com.mtjin.nomoneytrip.views.dialog

import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.Window
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.FragmentManager
import com.mtjin.nomoneytrip.R

class LottieDialogFragment : DialogFragment() {
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        dialog?.requestWindowFeature(Window.FEATURE_NO_TITLE)
        dialog?.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))

        isCancelable = false
        return inflater.inflate(R.layout.fragment_lottie_dialog, container, false)
    }

    companion object {
        fun newInstance(
        ): LottieDialogFragment {
            return LottieDialogFragment()
        }
    }

    override fun show(manager: FragmentManager, tag: String?) {
        val ft = manager.beginTransaction()
        ft.add(this, tag)
        ft.commitAllowingStateLoss()
    }
}

 

 

 

[BaseFragment]

showProgressDialog() 가 로띠 부분입니다.

package com.mtjin.nomoneytrip.base

import android.content.Context
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.annotation.LayoutRes
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
import androidx.fragment.app.Fragment
import com.mtjin.nomoneytrip.views.dialog.LottieDialogFragment

abstract class BaseFragment<B : ViewDataBinding>(
    @LayoutRes val layoutId: Int
) : Fragment() {
    lateinit var binding: B
    protected lateinit var thisContext: Context
    lateinit var lottieDialog: LottieDialogFragment

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        binding = DataBindingUtil.inflate(inflater, layoutId, container, false)
        thisContext = inflater.context
        lottieDialog = LottieDialogFragment.newInstance()
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        binding.lifecycleOwner = this
        init()
    }

    abstract fun init()

    protected fun showToast(msg: String) =
        Toast.makeText(context, msg, Toast.LENGTH_SHORT).show()

    fun showProgressDialog() {
        lottieDialog.show(
            requireActivity().supportFragmentManager,
            lottieDialog.tag
        )
    }

    fun hideProgressDialog() {
        if (lottieDialog.isAdded) {
            lottieDialog.dismissAllowingStateLoss()
        }
    }
}

 

 

 

[BaseViewModel]

showLottieProgress() 가 로띠 부분입니다.

실제 뷰모델에서 _isLottieLoading.value = true/ false 를 해주시면 됩니다.

package com.mtjin.nomoneytrip.base

import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.mtjin.nomoneytrip.utils.SingleLiveEvent
import io.reactivex.disposables.CompositeDisposable

abstract class BaseViewModel : ViewModel() {
    protected val compositeDisposable = CompositeDisposable()


    private var _backClick = SingleLiveEvent<Unit>()
    val backClick: LiveData<Unit> get() = _backClick
    private val _isLoading = MutableLiveData<Boolean>(false)
    val isLoading: LiveData<Boolean> get() = _isLoading
    private val _isLottieLoading = MutableLiveData<Boolean>(false)
    val isLottieLoading: LiveData<Boolean> get() = _isLottieLoading

    override fun onCleared() {
        compositeDisposable.dispose()
        super.onCleared()
    }

    fun showProgress() {
        _isLoading.value = true
    }

    fun hideProgress() {
        _isLoading.value = false
    }

    fun showLottieProgress() {
        _isLottieLoading.value = true
    }

    fun hideLottieProgress() {
        _isLottieLoading.value = false
    }

    fun onBackClick() {
        _backClick.call()
    }

}

 

 

 

 

 

 

 

 

댓글과 공감은 큰 힘이 됩니다 감사합니다. !!

728x90
Comments