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

I Can Animate and So Can You (mdevcon)

I Can Animate and So Can You (mdevcon)

A medium-length version of a talk I gave about Android animations at mdevcon in Amsterdam 2014.

Keynote version: http://goo.gl/7KuSxP

Daniel Lew

March 08, 2014
Tweet

More Decks by Daniel Lew

Other Decks in Programming

Transcript

  1. I Can Animate and So
    Can You
    Daniel Lew, Mar. 8, 2014

    View full-size slide

  2. Typical Animation
    Demo

    View full-size slide

  3. What Can Be Done

    View full-size slide

  4. Revelation #1
    Every animation is unique

    View full-size slide

  5. Revelation #2
    Animation code is not pretty

    View full-size slide

  6. Revelation #3
    Animations first
    Animate

    View full-size slide

  7. Revelation #4
    Animate for 4.x+

    View full-size slide

  8. Ditch 2.x
    • Poor performance

    • Can't use modern tricks

    • Backup: NineOldAndroids

    View full-size slide

  9. Ditch 3.x
    • Tiny userbase

    • ViewPropertyAnimator -
    Introduced 3.1

    • TextureView -
    Introduced 4.0

    View full-size slide

  10. Building Animations
    • Figure out what
    attributes to animate

    • Design View hierarchy

    • Measure attribute start/
    end values

    • Setup and run animators

    View full-size slide

  11. Determining Attributes
    • Alpha - every element

    • Translate - every row

    • Translate - details
    header/footer

    • Scale - details rows (a
    hardcore fake)

    • Fading background - not
    needed!

    View full-size slide

  12. View Hierarchy
    • Animation informs View
    hierarchy

    • Here, rows go
    underneath split action
    bar

    View full-size slide

  13. Measuring Views
    • Problem: Views not measured until
    sometime after inflation

    • ViewTreeObserver - lets you know when a
    View has been measured

    • Two options: OnGlobalLayoutListener,
    OnPreDrawListener

    View full-size slide

  14. ViewTreeObserver
    Pattern
    !
    final View view = findViewById(R.id.view);
    view.getViewTreeObserver().addOnPreDrawListener(new
    OnPreDrawListener() {
    public boolean onPreDraw() {
    view.getViewTreeObserver().removeOnPreDrawListener(this);
    // Measure here!
    return true;
    }
    });

    View full-size slide

  15. Measuring "After"
    • Align to other existing Views

    • Create invisible "dummy" Views to animate
    towards

    View full-size slide

  16. Running Animators
    • ObjectAnimator - animate!

    • AnimatorSet - synchronize multiple
    Animators

    • AnimatorListener - setup and cleanup

    • Canceling Animators w/ reverse()

    View full-size slide

  17. Property Animators
    • Generic animation framework

    • Animates *any* value over time

    • Basic building block for most animations

    View full-size slide

  18. ObjectAnimator
    • Type of property animator

    • Used for animating essential View properties

    • Position (or translation)

    • Rotation

    • Scale

    • Alpha

    • Can be used on custom View properties

    View full-size slide

  19. ObjectAnimator
    // Uses setAlpha() and getAlpha() to animate
    ObjectAnimator.ofFloat(myView, "alpha", 0, 1).start();
    !
    !
    !
    // Uses built-in property to avoid reflection
    ObjectAnimator.ofFloat(myView, View.ALPHA, 1).start();

    View full-size slide

  20. AnimatorSet
    !
    ObjectAnimator one = ObjectAnimator.ofFloat(view1,
    "alpha", 1);
    ObjectAnimator two = ObjectAnimator.ofFloat(view2,
    "alpha", 1);
    !
    AnimatorSet set = new AnimatorSet();
    set.playTogether(one, two);
    set.start();

    View full-size slide

  21. Animator Listeners
    !
    ObjectAnimator anim = ObjectAnimator.ofFloat(view,
    "alpha", 1);
    anim.addListener(new AnimatorListenerAdapter() {
    public void onAnimationEnd(Animator animation) {
    // Clean-up code here
    }
    });
    anim.start();

    View full-size slide

  22. Reversing Course
    • ValueAnimator.reverse()

    • Useful for smoothly canceling an animator

    • Can recursively traverse AnimatorSet for
    ValueAnimators

    View full-size slide

  23. Questions So Far?

    View full-size slide

  24. Performance
    • Choppy animation == painful

    • Performance cannot be an afterthought

    • Smooth animations informs structure

    View full-size slide

  25. Performance
    Breakdown
    • Layout - size/location of Views

    • Draw - what's inside Views

    • Render - pushing it on screen

    View full-size slide

  26. Layout Performance
    • Initiated by
    View.requestLayout()

    • Slow - avoid at all costs

    • Can sneak up on you

    View full-size slide

  27. Draw Performance
    • Initiated by
    View.invalidate()

    • How animations are run

    View full-size slide

  28. Render Performance
    • Initiated every time
    pixels are put on screen

    • Varies with pixel count/
    speed of device

    • Try to reduce overdraw

    View full-size slide

  29. Profile GPU Rendering
    • Blue - Draw

    • Red - Process

    • Orange - Execute

    • Green line - your goal

    View full-size slide

  30. Show GPU Overdraw
    • Shows overdrawn pixels

    • Best to worst: nothing,
    blue, green, red, dark red

    • Some overdraw
    necessary, but reduce if
    possible

    View full-size slide

  31. Other Profilers
    • Traceview - Breakdown of method calls

    • Systrace - Measures everything on system

    • OpenGL Traces - Every single OpenGL call

    View full-size slide

  32. Profile Warnings
    • Profilers can be inaccurate

    • One profiling tool at a time, please

    • Profile multiple devices

    View full-size slide

  33. Optimization: Layers
    • Layers store drawn
    Views for reuse

    • Reduces drawing during
    animation

    • Reduces overdraw
    during animation

    View full-size slide

  34. Layers
    LinearLayout
    ImageView TextView TextView

    View full-size slide

  35. Layers
    LinearLayout
    ImageView TextView TextView
    LinearLayout

    View full-size slide

  36. Layer Pattern
    !
    final View myView = findViewById(R.id.my_view);
    myView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
    myView.animate()
    .translationX(50)
    .setListener(new AnimatorListenerAdapter() {
    public void onAnimationEnd(Animator animation) {
    myView.setLayerType(View.LAYER_TYPE_NONE, null);
    }
    })
    .start();

    View full-size slide

  37. Layer Caveats
    • Warning: redrawing a
    layer is *slower* than
    non-layer

    • DisplayLists will rebuild
    layers when necessary

    • Layering simple Views
    just hurts performance

    View full-size slide

  38. Other Animation Tools

    View full-size slide

  39. Custom Views
    • Custom Views easier
    than they sound!

    • Animate your own
    attributes

    • Simplify animation via
    isolation

    • Cheat for performance’s
    sake

    View full-size slide

  40. set directions
    • View methods: setLeft(),
    setRight(), setTop(),
    setBottom()

    • Change layout without
    requesting layout!

    • Parent layout blows
    away values, may have to
    block

    View full-size slide

  41. Drawable Animations
    • AnimationDrawable - frame animations

    • Custom animated Drawable in a View

    • Drawable.setCallback()

    • View.verifyDrawable()

    View full-size slide

  42. SurfaceView and
    TextureView
    • Great for constantly
    animated View

    • SurfaceView is fast but is
    weird

    • TextureView is 4.0+, but
    can be moved around

    View full-size slide

  43. Resources
    • Android: goo.gl/4aZIzM

    • DevBytes: goo.gl/QeTM9B

    • Chet Haase: graphics-geek.blogspot.com/

    • Romain Guy: curious-creature.org

    • Google IO Sessions (esp. with Haase/Guy)

    View full-size slide

  44. Thank You!
    • Blog: http://blog.danlew.net

    • Movies App Source: http://goo.gl/WiRTlQ

    • Twitter: @danlew42

    View full-size slide