Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

Kyash + Google Pay

Slide 3

Slide 3 text

Kyash loves DataBinding ❤ • We are using DataBinding a lot.
 Kyash͸DataBindingΊͬͪΌ࢖ͬͯΔ • Applying not only variables but also events like click and scroll.
 ม਺͚ͩͰ͸ͳ͘ɺΫϦοΫ΍εΫϩʔϧͱ͍ͬͨΠϕϯτ΋ద༻ͯ͠Δ

Slide 4

Slide 4 text

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Λ঺հ͢Δ

Slide 5

Slide 5 text

39 Animation in Kyash History tab • When the user receives 39 Yen (similar pronunciation “Thank you” in Japanese), Fireworks Lottie Animation plays.
 Ϣʔβʔ͕39ԁΛड͚औͬͨ࣌ɺLottieՖՐͷΞχϝʔγϣϯ͕࠶ੜ͞ΕΔ

Slide 6

Slide 6 text

Layout xml

Slide 7

Slide 7 text

Layout xml • 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

Slide 8

Slide 8 text

Layout xml • animation39FileName = "lottie/Timeline39Animation.json" • main
 |— assets
 |— lottie
 |— Timeline39Animation.json

Slide 9

Slide 9 text

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() }

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

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.

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

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() }

Slide 14

Slide 14 text

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() }

Slide 15

Slide 15 text

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() }

Slide 16

Slide 16 text

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() }

Slide 17

Slide 17 text

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() }

Slide 18

Slide 18 text

That’s it! Super simple.

Slide 19

Slide 19 text

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


Slide 20

Slide 20 text

Thanks!