$30 off During Our Annual Pro Sale. View Details »

In a World of Pure Android Animation 🍭🍫

In a World of Pure Android Animation 🍭🍫

Have you dreamed of deliciously sweet animations in your app but have no idea where to start? 🍫 What about creating some delightful UI treats to keep your users intrigued and wanting to discover more? 🍦 Join Rebecca on this journey into a World of Pure Android Animation ✨. From creating custom view animations on a Canvas to using MotionLayout to create complex layout animations, there is something for everyone. We will also see how to create your own AnimatedVectorDrawable using Shape Shifter. No golden ticket required.

Rebecca is an Android Engineer from South Africa. She is a Google Developer Expert in Android and loves helping other developers learn new things. During the day, she works for a company called Over, where she helps to contribute to the graphic design app on a day to day basis. She loves travelling and baking.

Links:
https://bit.ly/animation-ex
https://bit.ly/cl-samples
https://proandroiddev.com/android-bring-life-to-your-custom-view-8604ab3967b3
https://android-developers.googleblog.com/2011/05/introducing-viewpropertyanimator.html
https://twitter.com/chrisbanes/status/1030365248694312960
https://youtu.be/N_x7SV3I3P0
https://medium.com/s23nyc-tech/geometric-android-animations-using-the-canvas-dd687c43f3f4

Rebecca Franks

April 23, 2019
Tweet

More Decks by Rebecca Franks

Other Decks in Programming

Transcript

  1. View Slide

  2. View Slide

  3. Hi
    Android Developer @ Over
    Google Developer Expert in Android
    @riggaroo
    riggaroo.co.za
    I’m Rebecca Franks
    "

    View Slide

  4. JellyToolbar
    https://github.com/Yalantis/JellyToolbar
    Alexio Mota & Nick Butcher
    https://twitter.com/alexiomota
    TiVi - Chris Banes
    https://github.com/chrisbanes/tivi
    Examples of Animations
    Android Dev Summit 2018 App

    View Slide

  5. But how?

    View Slide

  6. View Slide

  7. All Kinds of Animations ✨
    • AnimatedVectorDrawables
    • Shape Shifter
    • Property Animations
    • Custom View Animations
    • Physics-based Animations
    • MotionLayout

    View Slide

  8. Sample App - Github
    bit.ly/animation-ex

    View Slide

  9. View Slide

  10. AnimatedVectorDrawable
    • VectorDrawable and AnimatorSet / ObjectAnimator
    • VectorDrawable: Scalable, density-independent asset
    • Represented by paths
    • Subset of SVG spec
    • Fire and forget animation

    View Slide

  11. View Slide

  12. View Slide

  13. Shape Shifter
    • Create Animations for Android, iOS and Web
    • Animate pathData, alpha, color, strokeWidth
    • Made by Alex Lockwood

    View Slide

  14. View Slide

  15. Step 1 : Choose/Make your icons
    Step 2 : Import them into Shape Shifter
    Step 3 : Animate pathData between them
    Step 4 : Magic?

    View Slide

  16. Step 1 : Choose your icons
    Might need to split the icons up logically in Sketch

    View Slide

  17. Step 2 : Import into Shape Shifter

    View Slide

  18. Step 3 : Animate pathData

    View Slide

  19. (Maybe) Step 4 : Pair sub paths

    View Slide

  20. (Maybe) Step 5 : Correct points

    View Slide

  21. Final Animation

    View Slide

  22. AnimatedVectorDrawable
    • Export from Shape Shifter as AVD file

    View Slide

  23. val drawable = AppCompatResources.getDrawable(this, R.drawable.avd_center_justify)
    imageViewAvd.setImageDrawable(drawable)
    AnimatedVectorDrawableCompat.registerAnimationCallback(drawable, object :
    Animatable2Compat.AnimationCallback() {
    override fun onAnimationEnd(drawable: Drawable?) {
    Toast.makeText(applicationContext, "Animation finished", Toast.LENGTH_LONG).show()
    }
    })
    imageViewAvd.setOnClickListener {
    (drawable as Animatable).start()
    }

    View Slide

  24. val drawable = AppCompatResources.getDrawable(this, R.drawable.avd_center_justify)
    imageViewAvd.setImageDrawable(drawable)
    AnimatedVectorDrawableCompat.registerAnimationCallback(drawable, object :
    Animatable2Compat.AnimationCallback() {
    override fun onAnimationEnd(drawable: Drawable?) {
    Toast.makeText(applicationContext, "Animation finished", Toast.LENGTH_LONG).show()
    }
    })
    imageViewAvd.setOnClickListener {
    (drawable as Animatable).start()
    }

    View Slide

  25. val drawable = AppCompatResources.getDrawable(this, R.drawable.avd_center_justify)
    imageViewAvd.setImageDrawable(drawable)
    AnimatedVectorDrawableCompat.registerAnimationCallback(drawable, object :
    Animatable2Compat.AnimationCallback() {
    override fun onAnimationEnd(drawable: Drawable?) {
    Toast.makeText(applicationContext, "Animation finished", Toast.LENGTH_LONG).show()
    }
    })
    imageViewAvd.setOnClickListener {
    (drawable as Animatable).start()
    }

    View Slide

  26. View Slide

  27. View Slide

  28. Lottie
    • Useful for Cross platform complex Animations
    • Created by Airbnb
    • Use AfterEffects & export using Bodymovin’
    • setProgress()
    • Download on demand
    • lottiefiles.com

    View Slide

  29. Lottie
    android:id="@+id/animation_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:lottie_rawRes="@raw/happy_birthday"
    app:lottie_loop="true"
    app:lottie_autoPlay="true" />

    View Slide

  30. View Slide

  31. ViewPropertyAnimator
    • Animate specific, common properties on a view
    • Fire and Forget
    • User-friendly API to use
    • More efficient when doing multiple animations at once

    View Slide

  32. Property Animations
    imageView
    .animate()
    .alpha(0f)
    .rotationBy(360f)
    .scaleX(0f)
    .scaleY(0f)
    .setDuration(2000)
    .withEndAction {
    // Animation Finished
    }
    .start()

    View Slide

  33. View Slide

  34. View Slide

  35. Custom View Animations
    • Built in animations just don’t cut it
    • Custom properties on a view
    • Color, radius, shadow, matrix

    View Slide

  36. PropertyValuesHolder
    • Holds info about a property & values during animation
    • Create animations with ValueAnimator or ObjectAnimator

    View Slide

  37. fun animateSizeColorChange(toSize: Float, @ColorInt toColor: Int) {
    val propColor = PropertyValuesHolder.ofInt(PROP_TEXT_COLOR, textColor, toColor)
    val propTextSize = PropertyValuesHolder.ofFloat(PROP_TEXT_SIZE, size, toSize)
    ValueAnimator.ofPropertyValuesHolder(propColor, propertyTextSize).apply {
    setEvaluator(ArgbEvaluator())
    duration = 500
    addUpdateListener { animation ->
    val textSize = animation.getAnimatedValue(PROP_TEXT_SIZE) as Float
    val textColor = animation.getAnimatedValue(PROP_TEXT_COLOR) as Int
    setTextSizeColor(textSize, textColor)
    }
    start()

    View Slide

  38. fun animateSizeColorChange(toSize: Float, @ColorInt toColor: Int) {
    val propColor = PropertyValuesHolder.ofInt(PROP_TEXT_COLOR, textColor, toColor)
    val propTextSize = PropertyValuesHolder.ofFloat(PROP_TEXT_SIZE, size, toSize)
    ValueAnimator.ofPropertyValuesHolder(propColor, propertyTextSize).apply {
    setEvaluator(ArgbEvaluator())
    duration = 500
    addUpdateListener { animation ->
    val textSize = animation.getAnimatedValue(PROP_TEXT_SIZE) as Float
    val textColor = animation.getAnimatedValue(PROP_TEXT_COLOR) as Int
    setTextSizeColor(textSize, textColor)
    }
    start()
    }
    }

    View Slide

  39. View Slide

  40. View Slide

  41. View Slide

  42. Physics-Based Animations / Dynamic Animations
    • Driven by force - ie gestures
    • More natural looking
    • Don’t specify duration
    • Can reconfigure and velocity is recalculated
    • SpringAnimation & FlingAnimation

    View Slide

  43. Fling Animation
    FlingAnimation(imageView, DynamicAnimation.TRANSLATION_Y)
    .apply {
    setStartVelocity(700f) // Pixels per second
    friction = 0.1f
    }.start()
    https://developer.android.com/guide/topics/graphics/fling-animation

    View Slide

  44. View Slide

  45. Spring
    Animation

    View Slide

  46. Spring Animation
    private val floatPropertyAnimX = object : FloatPropertyCompat(PROPERTY_X) {
    override fun setValue(dropper: ColorView?, value: Float) {
    dropper?.setDropperX(value)
    }
    override fun getValue(dropper: ColorView?): Float {
    return dropper?.getDropperX() ?: 0f
    }
    }

    View Slide

  47. Spring Animation
    SpringAnimation(this, floatPropertyAnimX, point.x).apply {
    spring.stiffness = SpringForce.STIFFNESS_MEDIUM
    spring.dampingRatio = SpringForce.DAMPING_RATIO_MEDIUM_BOUNCY
    start()
    }

    View Slide

  48. Spring Animation - KTX ✨
    springAnimationOf(::setDropperX, ::getDropperX, point.x).apply {
    spring.stiffness = SpringForce.STIFFNESS_MEDIUM
    spring.dampingRatio = SpringForce.DAMPING_RATIO_MEDIUM_BOUNCY
    start()
    }

    View Slide

  49. STIFFNESS_LOW STIFFNESS_MEDIUM STIFFNESS_HIGH

    View Slide

  50. DAMPING_RATIO_LOW_BOUNCY DAMPING_RATIO_MEDIUM_BOUNCY DAMPING_RATIO_HIGH_BOUNCY

    View Slide

  51. View Slide

  52. MotionLayout
    • Subclass of ConstraintLayout
    • Complex UI element animations
    • Gesture driven UI changes
    • Useful for transitions between layout states
    • Defined in XML

    View Slide

  53. MotionLayout - Basic Example
    • dragUp on RecyclerView

    View Slide

  54. xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:android="http://schemas.android.com/apk/res/android">
    app:constraintSetStart="@id/start"
    app:constraintSetEnd="@id/end"
    app:duration="1000">
    app:touchAnchorId="@+id/recyclerViewStatus"
    app:touchAnchorSide="top"
    app:dragDirection="dragUp" />

    View Slide

  55. app:constraintSetStart="@id/start"
    app:constraintSetEnd="@id/end"
    app:duration="1000">
    app:touchAnchorId="@+id/recyclerViewStatus"
    app:touchAnchorSide="top"
    app:dragDirection="dragUp" />







    android:layout_width="40dp"

    View Slide






  56. android:layout_width="40dp"
    android:layout_height="40dp"
    android:layout_marginTop="16dp"
    app:layout_constraintTop_toTopOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    android:layout_marginStart="16dp">






    View Slide

  57. View Slide

  58. MotionLayout - KeyFrames
    • Specify certain animations at certain time within
    complex animation
    Start state End state
    framePosition = 0 100
    60
    View is fully visible

    View Slide

  59. app:constraintSetStart="@id/start"
    app:constraintSetEnd="@id/end"
    app:interpolator="easeInOut"
    app:duration="2000">

    android:alpha="1"
    app:framePosition="60"
    android:translationY="0dp"
    app:target=“@id/imageViewBannerMiddle”/>

    […]

    View Slide

  60. subscriptionMotionLayout.transitionToEnd()

    View Slide

  61. KeyFrames

    View Slide

  62. Examples
    • bit.ly/animation-ex
    • bit.ly/cl-samples

    View Slide

  63. Recap
    • AVDs
    • Shape Shifter
    • Lottie
    • Property Animations
    • Custom View Animations
    • MotionLayout

    View Slide

  64. There are other ways…
    • Transitions
    • TransitionManager
    • Activity Scenes
    • AnimatorSets
    • ….

    View Slide

  65. Spend time learning the available tools, so you can
    make some great animations ✨

    View Slide

  66. @riggaroo

    View Slide

  67. Resources
    • https://proandroiddev.com/android-bring-life-to-your-custom-
    view-8604ab3967b3
    • https://android-developers.googleblog.com/2011/05/
    introducing-viewpropertyanimator.html
    • https://twitter.com/chrisbanes/status/1030365248694312960


    View Slide

  68. Resources
    • https://youtu.be/N_x7SV3I3P0
    • https://medium.com/s23nyc-tech/geometric-android-
    animations-using-the-canvas-dd687c43f3f4


    View Slide