I Can Animate and So Can You

D225ebf0faa666ac7655cc7e4689283c?s=47 Daniel Lew
November 15, 2013

I Can Animate and So Can You

A talk about View animations on Android.

Original Keynote files (with animations): https://db.tt/qnUnoHpF

D225ebf0faa666ac7655cc7e4689283c?s=128

Daniel Lew

November 15, 2013
Tweet

Transcript

  1. I Can Animate and So Can You Daniel Lew, Nov.

    15 2013
  2. What I Used To Do • Cross fades • Graph

    scale
  3. Typical Animation Demo

  4. What Can Be Done

  5. Revelations (I was thinking about animations all wrong)

  6. Revelation #1 Every animation is unique

  7. Revelation #2 Animation code is not pretty

  8. Revelation #3 Animations first Animate

  9. Revelation #4 Animate for 4.x+

  10. Ditch 2.x • Poor performance • Can't use modern tricks

    • Backup: NineOldAndroids
  11. Ditch 3.x • Tiny userbase • ViewPropertyAnimator - Introduced 3.1

    • TextureView - Introduced 4.0
  12. Building Animations • Figure out what attributes to animate •

    Design View hierarchy • Measure attribute start/ end values • Setup and run animators
  13. View Attributes • Basic animation attributes • Translation • Scale

    • Rotation • Alpha • Custom attributes can be added
  14. Determining Attributes • What needs to happen? • What can

    be faked?
  15. Determining Attributes • Alpha - every element • Translate -

    every row • Translate - details header/footer • Scale - details rows (a hardcore fake) • Fading background - not needed!
  16. View Hierarchy • Animation informs View hierarchy • Rows go

    underneath split action bar • Classic problem: Views cannot animate outside their parent's bounds
  17. Measuring Views • Problem: Views not measured until sometime after

    inflation • ViewTreeObserver - lets you know when a View has been measured • OnGlobalLayoutListener • OnPreDrawListener • Can cancel drawing before it happens
  18. 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; } });
  19. Measuring "After" • Align to other existing Views • Create

    invisible "dummy" Views to animate towards • Start in the correct position, animate towards it
  20. Running Animators • ObjectAnimator - animate! • AnimatorSet - synchronize

    multiple Animators • AnimatorListener - setup and cleanup • Canceling Animators w/ reverse()
  21. Property Animators • Generic animation framework • Animates any value

    over time • Not limited to just visual animations • Basic building block for most animations
  22. ObjectAnimator • Type of property animator • Used for animating

    essential View properties • Position (or translation) • Rotation • Scale • Alpha • Can be used on custom View properties
  23. ObjectAnimator // Uses built-in property to avoid reflection ObjectAnimator.ofFloat(myView, View.ALPHA,

    1).start(); // Alternative, with PropertyValuesHolder // Depends on setAlpha() and getAlpha() PropertyValuesHolder pvh = PropertyValuesHolder.ofFloat("alpha", 0, 1); ObjectAnimator.ofPropertyValuesHolder(mySecondView, pvh);
  24. 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();
  25. Animator Listeners ObjectAnimator anim = ObjectAnimator.ofFloat(view, "alpha", 1); anim.addListener(new AnimatorListenerAdapter()

    { public void onAnimationEnd(Animator animation) { // Clean-up code here } }); anim.start();
  26. Reversing Course • ValueAnimator.reverse() • Useful for smoothly canceling an

    animator • Can recursively traverse AnimatorSet for ValueAnimators
  27. Performance • Choppy animation == painful • Performance cannot be

    an afterthought • Smooth animations informs View structure
  28. Performance Breakdown • Layout - size/location of Views • Draw

    - what's inside Views • Render - pushing it on screen
  29. Layout Performance • Initiated by View.requestLayout() • Slow - avoid

    at all costs • Can sneak up on you
  30. Draw Performance • Initiated by View.invalidate() • Acceptable during animations

    • Can be optimized with layers
  31. Render Performance • Initiated every time pixels are put on

    screen • Varies with pixel count/ speed of device • Try to reduce overdraw
  32. Profiling

  33. Demo: Profiling Movies

  34. Profile GPU Rendering • Blue - Draw • Red -

    Process • Orange - Execute • Green line - your goal
  35. Show GPU Overdraw • Shows overdrawn pixels • Best to

    worst: nothing, blue, green, red, dark red • Some overdraw necessary, but reduce if possible
  36. Show Hardware Layer Updates • Flashes green on HW layer

    redraw • If constantly flashing, you're doing something wrong!
  37. TraceView • Breakdown of methods • May skew results

  38. Systrace • Measures everything on the system • Much more

    accurate than TraceView • Bigger picture view
  39. OpenGL Traces

  40. Profile Warning • Can be inaccurate • One profiling tool

    at a time, please • Profile multiple devices
  41. Animation Optimizations

  42. Layers • Layers store drawn Views for reuse • Reduces

    drawing during animation • Reduces overdraw during animation
  43. 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();
  44. Layer Caveats • Warning: redrawing a layer is *slower* than

    non-layer • DisplayLists will rebuild layers when necessary • Layering simple Views just hurts performance
  45. Avoiding Layouts • Layouts == slow! • Layouts happen often

    • Subclass Views to block layouts
  46. 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(); } }
  47. Alpha Compositing • Needed for Views w/ multiple internal layers

    • Renders into offscreen buffer before fade • Slower, obviously
  48. hasOverlappingRendering() • New in API 16 • Off-screen rendering not

    required for all Views • Return false for any single-layer custom View
  49. TextView's Overlapping Rendering @Override public boolean hasOverlappingRendering() { return (getBackground()

    != null || mText instanceof Spannable || hasSelection()); }
  50. Other Animation Tools

  51. ViewPropertyAnimator • Retrieved via View.animate() • Shortcut for simple animations

    • Better performance when manipulating multiple values of a View • Cons: no easy way to reverse • Cons: no way to group animations
  52. ViewPropertyAnimator myView.animate() .alpha(1) .translationX(50) .setDuration(500) .start();

  53. Tween Animations • The original, so backwards compatible • Sometimes

    necessary • Fragment transactions • Limited to simple property changes • Not as rich as property animators
  54. Interpolators • Controls the speed of the animation • Accelerating

    • Decelerating • Overshoot • Makes animations feel "right"
  55. ActionBar Animations • ActionBar.show() • ActionBar.hide() • android:windowActionBarOverlay • Duration

    not customizable
  56. SurfaceView and TextureView • Generic drawing utilities • Great for

    constantly animated View
  57. SurfaceView vs. TextureView • TextureView is API 4.0+ • TextureView

    only works in HW accelerated windows • TextureView can, itself, be animated • SurfaceView uses hack and acts weird • TextureView is not as fast as SurfaceView
  58. Activity Window Animations • Custom tween animations between Activities •

    Limited to full-screen transitions • Activity.overridePendingTransition() • android:windowAnimationStyle
  59. Fragment Animations • Custom animations during Fragment transactions (adding/removing) •

    Limited to full-Fragment animations • Support library uses tween animations (instead of Animators)
  60. Fragment Animations • Fragment.onCreateAnimation() • Dynamic tweens • FragmentTransaction.setCustomAnimations() •

    Pre-built tweens • FragmentTransaction.setTransition() and setTransitionStyle() • Pre-defined animation styles
  61. Complex Fragment/ Activity Animations • Transition state • A -->

    A + B --> B • Invisible Fragments/transparent Activities • Single Activity, many Fragments/Views • ...Insert your solution here!
  62. View offsets • View.offsetLeftAndRight() • View.offsetTopAndBottom() • Performs well •

    Backwards compatible
  63. set directions • View methods: setLeft(), setRight(), setTop(), setBottom() •

    Skip layout during animations • Parent layout blows away values, may have to block
  64. Drawable Animations • AnimationDrawable - frame animations • Custom animated

    Drawable in a View • Drawable.setCallback() • View.verifyDrawable()
  65. layoutAnimation • LayoutAnimation Controller • Staggers animations when Views are

    displayed • Useful for grid views • Useful for widget animations
  66. LayoutTransition • Automatic animations on layout changes • Runs when

    views are added/removed
  67. ViewOverlay • New in API 4.3 • Generically add Drawables

    connected to Views • Can render outside parent bounds
  68. TransitionManager • New in 4.4 • Transition automatically between two

    ViewGroups • Not fully backwards compatible (yet)
  69. 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)
  70. Thank You! • Blog: http://daniel-codes.blogspot.com/ • Movies App Source: http://goo.gl/WiRTlQ

    • Twitter: @danlew42 • Plus: https://plus.google.com/+DanielLew/