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

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 Slide

  2. Typical Animation
    Demo

    View Slide

  3. What Can Be Done

    View Slide

  4. Revelations

    View Slide

  5. Revelation #1
    Every animation is unique

    View Slide

  6. Revelation #2
    Animation code is not pretty

    View Slide

  7. Revelation #3
    Animations first
    Animate

    View Slide

  8. Revelation #4
    Animate for 4.x+

    View Slide

  9. Ditch 2.x
    • Poor performance

    • Can't use modern tricks

    • Backup: NineOldAndroids

    View Slide

  10. Ditch 3.x
    • Tiny userbase

    • ViewPropertyAnimator -
    Introduced 3.1

    • TextureView -
    Introduced 4.0

    View Slide

  11. Building Animations
    • Figure out what
    attributes to animate

    • Design View hierarchy

    • Measure attribute start/
    end values

    • Setup and run animators

    View Slide

  12. Determining Attributes
    • Alpha - every element

    • Translate - every row

    • Translate - details
    header/footer

    • Scale - details rows (a
    hardcore fake)

    • Fading background - not
    needed!

    View Slide

  13. View Hierarchy
    • Animation informs View
    hierarchy

    • Here, rows go
    underneath split action
    bar

    View Slide

  14. 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 Slide

  15. 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 Slide

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

    • Create invisible "dummy" Views to animate
    towards

    View Slide

  17. Running Animators
    • ObjectAnimator - animate!

    • AnimatorSet - synchronize multiple
    Animators

    • AnimatorListener - setup and cleanup

    • Canceling Animators w/ reverse()

    View Slide

  18. Property Animators
    • Generic animation framework

    • Animates *any* value over time

    • Basic building block for most animations

    View Slide

  19. 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 Slide

  20. 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 Slide

  21. 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 Slide

  22. 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 Slide

  23. Reversing Course
    • ValueAnimator.reverse()

    • Useful for smoothly canceling an animator

    • Can recursively traverse AnimatorSet for
    ValueAnimators

    View Slide

  24. Questions So Far?

    View Slide

  25. Performance
    • Choppy animation == painful

    • Performance cannot be an afterthought

    • Smooth animations informs structure

    View Slide

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

    • Draw - what's inside Views

    • Render - pushing it on screen

    View Slide

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

    • Slow - avoid at all costs

    • Can sneak up on you

    View Slide

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

    • How animations are run

    View Slide

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

    • Varies with pixel count/
    speed of device

    • Try to reduce overdraw

    View Slide

  30. Profiling

    View Slide

  31. Profile GPU Rendering
    • Blue - Draw

    • Red - Process

    • Orange - Execute

    • Green line - your goal

    View Slide

  32. Show GPU Overdraw
    • Shows overdrawn pixels

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

    • Some overdraw
    necessary, but reduce if
    possible

    View Slide

  33. Other Profilers
    • Traceview - Breakdown of method calls

    • Systrace - Measures everything on system

    • OpenGL Traces - Every single OpenGL call

    View Slide

  34. Profile Warnings
    • Profilers can be inaccurate

    • One profiling tool at a time, please

    • Profile multiple devices

    View Slide

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

    • Reduces drawing during
    animation

    • Reduces overdraw
    during animation

    View Slide

  36. Layers
    LinearLayout
    ImageView TextView TextView

    View Slide

  37. Layers
    LinearLayout
    ImageView TextView TextView
    LinearLayout

    View Slide

  38. 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 Slide

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

    • DisplayLists will rebuild
    layers when necessary

    • Layering simple Views
    just hurts performance

    View Slide

  40. Other Animation Tools

    View Slide

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

    • Animate your own
    attributes

    • Simplify animation via
    isolation

    • Cheat for performance’s
    sake

    View Slide

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

    • Change layout without
    requesting layout!

    • Parent layout blows
    away values, may have to
    block

    View Slide

  43. Drawable Animations
    • AnimationDrawable - frame animations

    • Custom animated Drawable in a View

    • Drawable.setCallback()

    • View.verifyDrawable()

    View Slide

  44. SurfaceView and
    TextureView
    • Great for constantly
    animated View

    • SurfaceView is fast but is
    weird

    • TextureView is 4.0+, but
    can be moved around

    View Slide

  45. 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 Slide

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

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

    • Twitter: @danlew42

    View Slide