LottieAnimation with DataBinding

35e08efcf39d692f540047fb756eb4e3?s=47 konifar
October 09, 2018

LottieAnimation with DataBinding

Potatotips #55

35e08efcf39d692f540047fb756eb4e3?s=128

konifar

October 09, 2018
Tweet

Transcript

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

  2. Kyash + Google Pay

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

    lot.
 Kyash͸DataBindingΊͬͪΌ࢖ͬͯΔ • Applying not only variables but also events like click and scroll.
 ม਺͚ͩͰ͸ͳ͘ɺΫϦοΫ΍εΫϩʔϧͱ͍ͬͨΠϕϯτ΋ద༻ͯ͠Δ
  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Λ঺հ͢Δ
  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ՖՐͷΞχϝʔγϣϯ͕࠶ੜ͞ΕΔ
  6. Layout xml <com.airbnb.lottie.LottieAnimationView … 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"

    />
  7. Layout xml <com.airbnb.lottie.LottieAnimationView … 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
  8. Layout xml <com.airbnb.lottie.LottieAnimationView … 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
  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() }
  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
  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.
  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
  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() }
  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() }
  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() }
  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() }
  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() }
  18. That’s it! Super simple.

  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!
 ͨͿΜ૝૾ΑΓ؆୯͔ͩΒ࡞ͬͯΈͯ͸ʁ
 

  20. Thanks!