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

I Can Animate and So Can You (GDG)

Daniel Lew
February 08, 2014

I Can Animate and So Can You (GDG)

A medium-length version of a talk I gave about Android animations at GDG Devfest MN 2014.

Keynote version: http://goo.gl/CFWCll

Daniel Lew

February 08, 2014
Tweet

More Decks by Daniel Lew

Other Decks in Programming

Transcript

  1. I Can Animate and So
    Can You
    Daniel Lew, Feb. 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

    • Start in the correct position, animate
    towards it

    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. Performance
    • Choppy animation == painful

    • Performance cannot be an afterthought

    • Smooth animations informs View structure

    View Slide

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

    • Draw - what's inside Views

    • Render - pushing it on screen

    View Slide

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

    • Slow - avoid at all costs

    • Can sneak up on you

    View Slide

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

    • How animations are run

    • Can be optimized with
    layers

    View Slide

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

    • Varies with pixel count/
    speed of device

    • Try to reduce overdraw

    View Slide

  29. Profiling

    View Slide

  30. Profile GPU Rendering
    • Blue - Draw

    • Red - Process

    • Orange - Execute

    • Green line - your goal

    View Slide

  31. Show GPU Overdraw
    • Shows overdrawn pixels

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

    • Some overdraw
    necessary, but reduce if
    possible

    View Slide

  32. Show Hardware Layer
    Updates
    • Flashes green on HW
    layer redraw

    • If constantly flashing,
    you're doing something
    wrong!

    View Slide

  33. Profile Notes
    • Other tools: traceview, systrace, OpenGL
    traces

    • Profilers can be inaccurate

    • One profiling tool at a time, please

    • Profile multiple devices

    View Slide

  34. Optimizations

    View Slide

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

    • Reduces drawing during
    animation

    • Reduces overdraw
    during animation

    View 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 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 Slide

  38. Optimization: Avoiding
    Layouts
    • Layouts == slow!

    • Layouts happen often

    • Subclass Views to block layouts

    View Slide

  39. ImageView Blocking
    Layout
    !
    public void setIsFixedSize(boolean isFixedSize) {
    mIsFixedSize = isFixedSize;
    }
    !
    public void setImageBitmap(Bitmap bm) {
    mBlockMeasurement = true;
    super.setImageBitmap(bm);
    mBlockMeasurement = false;
    }
    !
    public void requestLayout() {
    if (!mBlockMeasurement || !mIsFixedSize) {
    super.requestLayout();
    }
    }

    View Slide

  40. Other Animation Tools

    View Slide

  41. 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

  42. Activity Window
    Animations
    • Custom tween animations between
    Activities

    • Limited to full-screen transitions

    • Activity.overridePendingTransition()

    • android:windowAnimationStyle

    View Slide

  43. Fragment Animations
    • Animations during Fragment transactions

    • Limited to full-Fragment animations

    • Fragment.onCreateAnimation()

    • FragmentTransaction.setCustomAnimations()

    • FragmentTransaction.setTransition() and
    setTransitionStyle()

    View Slide

  44. View offsets
    • View.offsetLeftAndRight()

    • View.offsetTopAndBottom()

    • Performs well

    • Backwards compatible

    View Slide

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

    • Change layout without
    requesting layout!

    • Parent layout blows
    away values, may have to
    block

    View Slide

  46. Drawable Animations
    • AnimationDrawable - frame animations

    • Custom animated Drawable in a View

    • Drawable.setCallback()

    • View.verifyDrawable()

    View Slide

  47. 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

  48. Thank You!
    • Blog: http://daniel-codes.blogspot.com/

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

    • Twitter: @danlew42

    • Plus: https://plus.google.com/+DanielLew/

    View Slide