Android Animations

Android Animations

My Animation talk from Droidcon New York City 2014

Original keynote w/ animations: https://www.dropbox.com/s/qhim23pfk3smsse/Android%20Animations.zip?dl=0
Sample app for camera distance tip:
https://github.com/dallasgutauckis/AnimationStation

98df39819d64b9533260e8f67790f7f4?s=128

Dallas Gutauckis

September 20, 2014
Tweet

Transcript

  1. ANDROID ANIMATIONS with Purpose (mostly)

  2. ABOUT ME • Dallas Gutauckis • Lead Android Engineer SeatGeek

    • Over 4 years of Android experience • Former co-organizer of GDG/Android Alliance Philly • Creator of mediocre parcelabler.com tool
  3. ANIMATIONS • WHY • With some examples! • WHAT •

    HOW
  4. WHY ANIMATE?

  5. WHY ANIMATE? • Ease transitions • Create a more natural

    experience • Inform on features • Whimsy
  6. EASE TRANSITIONS • Things don’t simply “change” in real life

    • Transition/move from A to B • Flip, slide, rotate, fall, etc
  7. SEATGEEK View transitions

  8. TUMBLR Compose

  9. NATURAL EXPERIENCE • Mimics physical properties • Mass • Elevation

    • Velocity
  10. GOOGLE+ Post list

  11. PLAY STORE Read more

  12. INFORM ON FUNCTION • Let the user know something is

    there • Great for gestures
  13. TUMBLR Follow

  14. PLAY MUSIC Current song

  15. PLAY MUSIC Next song

  16. WHIMSY Be delightful… …but don’t get in the way.

  17. SEATGEEK Announced not-logged-in

  18. SEATGEEK Performers not-logged-in

  19. FACEBOOK Pull-to-Refresh Loading

  20. HOW TO ANIMATE

  21. DISNEY ANIMATION: THE ILLUSION OF LIFE Ollie Johnston and Frank

    Thomas
  22. 12 BASIC PRINCIPLES OF ANIMATION

  23. SQUASH & STRETCH • Most real life objects react to

    impact and with elasticity
  24. ANTICIPATION • Often times, when things are getting ready to

    move, they make a movement in the opposite first • Baseball pitcher pulls arm back before going forward to throw the ball • Person crouches before jumping
  25. SLOW IN & OUT • Movement doesn’t just start and

    stop immediately • Running doesn’t just HAPPEN • You speed up before getting to your running speed • You slow down over time before coming to a stop • (Unless like Chet said, you hit a brick wall – good one Chet.)
  26. WHAT SHOULD WE ANIMATE?

  27. EVERYTHING

  28. EVERYTHING • Not really, but sorta… • Animate when… •

    Something changes • Follow a blog • Screen transitions • You want to hint at functionality • You want to show off (Whimsy) • Heart beating • Radar
  29. WHAT CAN WE ANIMATE? • Basic animations include • Alpha

    • Scale (x and y) • Rotation (x, y, and z) • Position (x, y) • Complex animations can animate anything you can program…
  30. HOW DO WE ANIMATE?

  31. QUICK WINS Simple platform functionality

  32. overridePendingTransition • overridePendingTransition(int enter, int exit) • Probably not something

    you’ll change often though
  33. setCustomAnimations (…) • Custom Fragment transitions • setCustomAnimations(int enter, int

    exit) • setCustomAnimations(int enter, int exit, int popEnter, int popExit) 13 (3.2)
  34. android:animateLayoutChanges="true" • Supports standard views and layouts • ListView •

    LinearLayout • RelativeLayout • Support for custom animations with LayoutTransition via setLayoutTransition(…) 11 (3.0)
  35. android:enterFadeDuration="..."
 android:exitFadeDuration="..." • <selector /> drawables • Animates between selector

    states 11 (3.0)
  36. MORE COMPLEX

  37. ObjectAnimator Honeycomb (3.0+)

  38. FEATURES • Duration • Value interpolator • Sets • Sequentially

    • Parallel (“Together”) • Listeners • Repetition • Animate any target (Object)
  39. EXAMPLE: ALPHA OUT ObjectAnimator alphaAnim = ObjectAnimator.ofFloat(myView, "alpha", 0); alphaAnim.setDuration(200);

    // Default is 300 alphaAnim.setInterpolator(new AccelerateDecelerateInterpolator()); alphaAnim.addListener(new Animator.AnimatorListener() { @Override public void onAnimationEnd(Animator animation) { myView.setVisibility(View.GONE); } @Override public void onAnimationStart(Animator animation) {} @Override public void onAnimationCancel(Animator animation) {} @Override public void onAnimationRepeat(Animator animation) {} }); alphaAnim.start(); 11 (3.0)
  40. EXAMPLE: ALPHA & TRANSLATIONX ObjectAnimator alphaAnim = ObjectAnimator.ofFloat(myView, "alpha", 0);

    ... alphaAnim.start(); ! ObjectAnimator translationXAnim = ObjectAnimator.ofFloat(myView, "translationX", -100); ! AnimatorSet set = new AnimatorSet(); set.playTogether( alphaAnim, translationXAnim ); ! set.start(); 11 (3.0)
  41. EXAMPLE: AnimatorSet AnimatorSet set = new AnimatorSet(); set.playTogether( ObjectAnimator.ofFloat(myView, "alpha",

    0), ObjectAnimator.ofFloat(myView, "translationX", -100) ); ! set.setInterpolator(new AccelerateDecelerateInterpolator()); set.setDuration(250); // Default is 300 set.addListener(new Animator.AnimatorListener() { @Override public void onAnimationEnd(Animator animation) { myView.setVisibility(View.GONE); } @Override public void onAnimationStart(Animator animation) {} @Override public void onAnimationCancel(Animator animation) {} @Override public void onAnimationRepeat(Animator animation) {} }); set.start(); 11 (3.0)
  42. EXAMPLE: HARDWARE ACCELERATION AnimatorSet set = new AnimatorSet(); set.playTogether( ObjectAnimator.ofFloat(myView,

    "alpha", 0), ObjectAnimator.ofFloat(myView, "translationX", -100) ); ! set.setInterpolator(new AccelerateDecelerateInterpolator()); set.setDuration(250); // Default is 300 set.addListener(new Animator.AnimatorListener() { @Override public void onAnimationEnd(Animator animation) { myView.setLayerType(View.LAYER_TYPE_NONE, null); myView.setVisibility(View.GONE); } @Override public void onAnimationStart(Animator animation) {} @Override public void onAnimationCancel(Animator animation) {} @Override public void onAnimationRepeat(Animator animation) {} }); ! myView.setLayerType(View.LAYER_TYPE_HARDWARE, null); ! set.start(); 16 (4.1)
  43. EXAMPLE: ARBITRARY VALUE myPancakeView.setPancakeCount(1); ! ObjectAnimator animator = ObjectAnimator.ofInt(myPancakeView, ”pancakeCount",

    20); ! animator.setDuration(250); // Default is 300 animator.addListener(new Animator.AnimatorListener() { @Override public void onAnimationEnd(Animator animation) { myPancakeView.addButter(); myPancakeView.addSyrup(); } @Override public void onAnimationStart(Animator animation) {} @Override public void onAnimationCancel(Animator animation) {} @Override public void onAnimationRepeat(Animator animation) {} }); ! animator.start();
  44. ViewPropertyAnimator Honeycomb MR1 (3.1+)

  45. FEATURES • Duration • Value interpolator • Listeners • Start

    delay • Fluent interface
  46. EXAMPLE: ALPHA OUT myView.animate() .alpha(0) .setDuration(250) // Default is 300

    .setInterpolator(new AccelerateDecelerateInterpolator()) .setListener(new Animator.AnimatorListener() { @Override public void onAnimationStart(Animator animation) {} @Override public void onAnimationEnd(Animator animation) { myView.setVisibility(View.GONE); } @Override public void onAnimationCancel(Animator animation) {} @Override public void onAnimationRepeat(Animator animation) {} }) .start(); 12 (3.1)
  47. EXAMPLE: ALPHA & TRANSLATIONX myView.animate() .alpha(0) .translationX(-100) .setDuration(250) // Default

    is 300 .setInterpolator(new AccelerateDecelerateInterpolator()) .setListener(new Animator.AnimatorListener() { @Override public void onAnimationStart(Animator animation) {} @Override public void onAnimationEnd(Animator animation) { myView.setVisibility(View.GONE); } @Override public void onAnimationCancel(Animator animation) {} @Override public void onAnimationRepeat(Animator animation) {} }) .start(); 12 (3.1)
  48. EXAMPLE: HARDWARE ACCELERATION myView.animate() .alpha(0) .translationX(-100) .withLayer() .setDuration(250) // Default

    is 300 .setInterpolator(new AccelerateDecelerateInterpolator()) .setListener(new Animator.AnimatorListener() { @Override public void onAnimationStart(Animator animation) {} @Override public void onAnimationEnd(Animator animation) { myView.setVisibility(View.GONE); } @Override public void onAnimationCancel(Animator animation) {} @Override public void onAnimationRepeat(Animator animation) {} }) .start(); 16 (4.1)
  49. A LITTLE MORE ON INTERPOLATORS

  50. INTERPOLATORS • Determine the output value based on input •

    Imagine animating from 0 to 1 over 100 frames • Normally just 0, 0.01, 0.02, 0.03, …, 1 • Now, something else…
  51. LINEAR Output 0 0.25 0.5 0.75 1 0 0.1 0.2

    0.3 0.4 0.5 0.6 0.7 0.8 0.9 1 Output output = input
  52. OVERSHOOT Output 0 0.3 0.6 0.9 1.2 0 0.1 0.2

    0.3 0.4 0.5 0.6 0.7 0.8 0.9 1 Output output = (input - 1) * (input - 1) * (([tension]2 + 1) * (input - 1) + [tension]2) + 1
  53. ACCELERATE + DECELERATE Output 0 0.25 0.5 0.75 1 0

    0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1 Output output = (cos((input + 1) * π) / 2) + 0.5
  54. TIPS, TRICKS, AND GOTCHAS

  55. X/Y ROTATION Bad

  56. • View#setCameraDistance(float) for rotationX/ rotationY

  57. X/Y ROTATION Good

  58. RE-RUNNING ANIMATIONS ON SAME VIEW myListener = new SimpleAnimatorListener(){ @Override

    public void onAnimationEnd(Animator animation){ v.animate().scaleYBy(0.5f).start(); } }; ! v.animate().scaleY(2f).setListener(myListener).start(); .setListener(null)
  59. VIEW CLIPPING What you want What you’ve got

  60. VIEW CLIPPING • Parent view encapsulates child drawing • Can’t

    draw outside • Refactor your layout
  61. AGAIN What you want What you’ve got

  62. WHAT YOU’VE GOT <FrameLayout> <LinearLayout bg=y> <View bg=r /> <View

    bg=g /> </Linearlayout> </FrameLayout>
  63. WHAT YOU WANT <RelativeLayout> <View bg=y/> <View bg=r/> <View br=g/>

    </RelativeLayout>
  64. VIEWOVERLAY • Could also use ViewOverlay • View.getOverlay().addView(myView); • Remove

    from parent first! 18 (4.3)
  65. VIEW COMPOSITING • VideoView extends SurfaceView • Behind the window

    • Can’t be efficiently moved, scaled, rotated • Can’t be rotated on X or Y axis at all
  66. VIEW COMPOSITING

  67. VIEW COMPOSITING What you want What you’ve got

  68. VIEW COMPOSITING • Use a TextureView instead • Only for

    animations/movement use cases 14 (4.0)
  69. BACKWARD COMPATIBILITY

  70. ALL THE INCOMPATIBILITY • NineOldAndroids • Open source! • Hyper-compatible

    (all the way to 1.0) • So much win! • Doesn’t support animateLayoutChanges • Doesn’t support LayoutTransition • Doesn’t support selector animations • ViewCompat • [set]hasTransientState
  71. HOMEWORK

  72. TRANSITIONMANAGER • Manages animations between layouts • Compatibility library/libraries already

    in the works 18 (4.3)
  73. MATERIAL & L • New hotness • Ripple • Reveal

    • Hero • Curved motion • View state changes L (?)
  74. RESOURCES https://speakerdeck.com/dlew/i-can-animate-and-so-can-you I Can Animate and So Can You Daniel

    Lew http://en.wikipedia.org/wiki/12_basic_principles_of_animation 12 Basic Principles of Animation Wikipedia, the free encyclopedia https://www.youtube.com/watch?v=ihzZrS69i_s Google I/O 2013: A Moving Experience Chet Haase & Romain Guy
  75. GO OUT AND ANIMATE

  76. THANKS Purple shirts seem to be a theme @DallasGutauckis /+DallasGutauckis

    Praise be to Duarte