Upgrade to Pro — share decks privately, control downloads, hide ads and more …

LottieAnimation with DataBinding

konifar
October 09, 2018

LottieAnimation with DataBinding

Potatotips #55

konifar

October 09, 2018
Tweet

More Decks by konifar

Other Decks in Programming

Transcript

  1. LottieAnimation
    with DataBinding
    potatotips #55
    2018/10/09 (Tue)
    @konifar Kyash Inc.

    View Slide

  2. Kyash + Google Pay

    View Slide

  3. Kyash loves DataBinding ❤
    • We are using DataBinding a lot.

    Kyash͸DataBindingΊͬͪΌ࢖ͬͯΔ
    • Applying not only variables but also events
    like click and scroll.

    ม਺͚ͩͰ͸ͳ͘ɺΫϦοΫ΍εΫϩʔϧͱ͍ͬͨΠϕϯτ΋ద༻ͯ͠Δ

    View Slide

  4. Custom BindingAdapter rocks!
    • Of course we are using Custom Binding
    Adapters.

    ΋ͪΖΜCustom BindingAdapter΋࢖ͬͯΔ
    • Today I’d like to introduce Adapter example
    called LottieAnimationViewExt.kt in Kyash
    app.

    ࠓ೔͸ศརͳKyashΞϓϦͰ࢖͍ͬͯΔLottieAnimationViewExt.kt ͱ͍͏
    AdaptersΛ঺հ͢Δ

    View Slide

  5. 39 Animation in Kyash History tab
    • When the user receives 39 Yen (similar
    pronunciation “Thank you” in Japanese),
    Fireworks Lottie Animation plays.

    Ϣʔβʔ͕39ԁΛड͚औͬͨ࣌ɺLottieՖՐͷΞχϝʔγϣϯ͕࠶ੜ͞ΕΔ

    View Slide

  6. Layout xml

    android:layout_width="56dp"
    android:layout_height="56dp"
    android:visibility="@{viewModel.animation39Visibility}"
    app:custom_lottie_autoPlay="@{true}"
    app:custom_lottie_fileName="@{viewModel.animation39FileName}"
    app:lottie_loop="true" />

    View Slide

  7. Layout xml

    android:layout_width="56dp"
    android:layout_height="56dp"
    android:visibility="@{viewModel.animation39Visibility}"
    app:custom_lottie_autoPlay="@{true}"
    app:custom_lottie_fileName="@{viewModel.animation39FileName}"
    app:lottie_loop="true" />
    • custom_lottie_autoPlay

    If it’s true, the animation plays automatically when the view is shown.

    trueͩͬͨΒView͕දࣔ͞Εͨ࣌ʹࣗಈతʹ࠶ੜ͞ΕΔ
    • custom_lottie_fileName

    lottie animation json file path.

    lottieΞχϝʔγϣϯͷjsonϑΝΠϧͷpath

    View Slide

  8. Layout xml

    android:layout_width="56dp"
    android:layout_height="56dp"
    android:visibility="@{viewModel.animation39Visibility}"
    app:custom_lottie_autoPlay="@{true}"
    app:custom_lottie_fileName="@{viewModel.animation39FileName}"
    app:lottie_loop="true" />
    • animation39FileName = "lottie/Timeline39Animation.json"
    • main

    |— assets

    |— lottie

    |— Timeline39Animation.json

    View Slide

  9. LottieAnimationViewExt.kt
    @BindingAdapter(
    value = [

    "custom_lottie_fileName", 

    "custom_lottie_autoPlay", 

    "custom_lottie_onAnimationEnd"

    ],
    requireAll = false
    )
    fun LottieAnimationView.setAnimation(

    jsonPath: String?, 

    autoStart: Boolean?, 

    animationListener: SimpleAnimatorListener?

    ) {

    }
    interface SimpleAnimatorListener {
    fun onAnimationEnd()
    }

    View Slide

  10. LottieAnimationViewExt.kt
    @BindingAdapter(
    value = [

    "custom_lottie_fileName", 

    "custom_lottie_autoPlay", 

    "custom_lottie_onAnimationEnd"

    ],
    requireAll = false
    )
    fun LottieAnimationView.setAnimation(

    jsonPath: String?, 

    autoStart: Boolean?, 

    animationListener: SimpleAnimatorListener?

    ) {

    }
    interface SimpleAnimatorListener {
    fun onAnimationEnd()
    }
    Custom Attributes

    View Slide

  11. LottieAnimationViewExt.kt
    @BindingAdapter(
    value = [

    "custom_lottie_fileName", 

    "custom_lottie_autoPlay", 

    "custom_lottie_onAnimationEnd"

    ],
    requireAll = false
    )
    fun LottieAnimationView.setAnimation(

    jsonPath: String?, 

    autoStart: Boolean?, 

    animationListener: SimpleAnimatorListener?

    ) {

    }
    interface SimpleAnimatorListener {
    fun onAnimationEnd()
    }
    If not required all, it’s okay to make
    Parameters Nullable.

    View Slide

  12. LottieAnimationViewExt.kt
    @BindingAdapter(
    value = [

    "custom_lottie_fileName", 

    "custom_lottie_autoPlay", 

    "custom_lottie_onAnimationEnd"

    ],
    requireAll = false
    )
    fun LottieAnimationView.setAnimation(

    jsonPath: String?, 

    autoStart: Boolean?, 

    animationListener: SimpleAnimatorListener?

    ) {

    }
    interface SimpleAnimatorListener {
    fun onAnimationEnd()
    }
    nullable

    View Slide

  13. LottieAnimationViewExt.kt
    fun LottieAnimationView.setAnimation(
    jsonPath: String?,
    autoStart: Boolean?,
    animationListener: SimpleAnimatorListener?) {
    if (autoStart == true && visibility == View.GONE) return
    if (jsonPath != null) setAnimation(jsonPath)
    if (animationListener != null) {
    addAnimatorListener(object : Animator.AnimatorListener {

    override fun onAnimationEnd(animation: Animator?) {
    animationListener.onAnimationEnd()
    }

    })
    }
    if (autoStart != null && autoStart) playAnimation()
    }
    interface SimpleAnimatorListener {
    fun onAnimationEnd()
    }

    View Slide

  14. LottieAnimationViewExt.kt
    fun LottieAnimationView.setAnimation(
    jsonPath: String?,
    autoStart: Boolean?,
    animationListener: SimpleAnimatorListener?) {
    if (autoStart == true && visibility == View.GONE) return
    if (jsonPath != null) setAnimation(jsonPath)
    if (animationListener != null) {
    addAnimatorListener(object : Animator.AnimatorListener {

    override fun onAnimationEnd(animation: Animator?) {
    animationListener.onAnimationEnd()
    }

    })
    }
    if (autoStart != null && autoStart) playAnimation()
    }
    interface SimpleAnimatorListener {
    fun onAnimationEnd()
    }

    View Slide

  15. LottieAnimationViewExt.kt
    fun LottieAnimationView.setAnimation(
    jsonPath: String?,
    autoStart: Boolean?,
    animationListener: SimpleAnimatorListener?) {
    if (autoStart == true && visibility == View.GONE) return
    if (jsonPath != null) setAnimation(jsonPath)
    if (animationListener != null) {
    addAnimatorListener(object : Animator.AnimatorListener {

    override fun onAnimationEnd(animation: Animator?) {
    animationListener.onAnimationEnd()
    }

    })
    }
    if (autoStart != null && autoStart) playAnimation()
    }
    interface SimpleAnimatorListener {
    fun onAnimationEnd()
    }

    View Slide

  16. LottieAnimationViewExt.kt
    fun LottieAnimationView.setAnimation(
    jsonPath: String?,
    autoStart: Boolean?,
    animationListener: SimpleAnimatorListener?) {
    if (autoStart == true && visibility == View.GONE) return
    if (jsonPath != null) setAnimation(jsonPath)
    if (animationListener != null) {
    addAnimatorListener(object : Animator.AnimatorListener {

    override fun onAnimationEnd(animation: Animator?) {
    animationListener.onAnimationEnd()
    }

    })
    }
    if (autoStart != null && autoStart) playAnimation()
    }
    interface SimpleAnimatorListener {
    fun onAnimationEnd()
    }

    View Slide

  17. LottieAnimationViewExt.kt
    fun LottieAnimationView.setAnimation(
    jsonPath: String?,
    autoStart: Boolean?,
    animationListener: SimpleAnimatorListener?) {
    if (autoStart == true && visibility == View.GONE) return
    if (jsonPath != null) setAnimation(jsonPath)
    if (animationListener != null) {
    addAnimatorListener(object : Animator.AnimatorListener {

    override fun onAnimationEnd(animation: Animator?) {
    animationListener.onAnimationEnd()
    }

    })
    }
    if (autoStart != null && autoStart) playAnimation()
    }
    interface SimpleAnimatorListener {
    fun onAnimationEnd()
    }

    View Slide

  18. That’s it!
    Super simple.

    View Slide

  19. Custom BindingAdapter rocks!
    • It makes ViewModel simple and easy to test.

    ViewModel͕γϯϓϧʹͳΓɺςετ΋ॻ͖΍͘͢ͳΔ
    • Maybe it’s easier to create BindingAdapter
    than you expected. Let’s try!

    ͨͿΜ૝૾ΑΓ؆୯͔ͩΒ࡞ͬͯΈͯ͸ʁ


    View Slide

  20. Thanks!

    View Slide