Slide 1

Slide 1 text

ANDROID ANIMATIONS with Purpose (mostly)

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

ANIMATIONS • WHY • With some examples! • WHAT • HOW

Slide 4

Slide 4 text

WHY ANIMATE?

Slide 5

Slide 5 text

WHY ANIMATE? • Ease transitions • Create a more natural experience • Inform on features • Whimsy

Slide 6

Slide 6 text

EASE TRANSITIONS • Things don’t simply “change” in real life • Transition/move from A to B • Flip, slide, rotate, fall, etc

Slide 7

Slide 7 text

SEATGEEK View transitions

Slide 8

Slide 8 text

TUMBLR Compose

Slide 9

Slide 9 text

NATURAL EXPERIENCE • Mimics physical properties • Mass • Elevation • Velocity

Slide 10

Slide 10 text

GOOGLE+ Post list

Slide 11

Slide 11 text

PLAY STORE Read more

Slide 12

Slide 12 text

INFORM ON FUNCTION • Let the user know something is there • Great for gestures

Slide 13

Slide 13 text

TUMBLR Follow

Slide 14

Slide 14 text

PLAY MUSIC Current song

Slide 15

Slide 15 text

PLAY MUSIC Next song

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

SEATGEEK Announced not-logged-in

Slide 18

Slide 18 text

SEATGEEK Performers not-logged-in

Slide 19

Slide 19 text

FACEBOOK Pull-to-Refresh Loading

Slide 20

Slide 20 text

HOW TO ANIMATE

Slide 21

Slide 21 text

DISNEY ANIMATION: THE ILLUSION OF LIFE Ollie Johnston and Frank Thomas

Slide 22

Slide 22 text

12 BASIC PRINCIPLES OF ANIMATION

Slide 23

Slide 23 text

SQUASH & STRETCH • Most real life objects react to impact and with elasticity

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

WHAT SHOULD WE ANIMATE?

Slide 27

Slide 27 text

EVERYTHING

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

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…

Slide 30

Slide 30 text

HOW DO WE ANIMATE?

Slide 31

Slide 31 text

QUICK WINS Simple platform functionality

Slide 32

Slide 32 text

overridePendingTransition • overridePendingTransition(int enter, int exit) • Probably not something you’ll change often though

Slide 33

Slide 33 text

setCustomAnimations (…) • Custom Fragment transitions • setCustomAnimations(int enter, int exit) • setCustomAnimations(int enter, int exit, int popEnter, int popExit) 13 (3.2)

Slide 34

Slide 34 text

android:animateLayoutChanges="true" • Supports standard views and layouts • ListView • LinearLayout • RelativeLayout • Support for custom animations with LayoutTransition via setLayoutTransition(…) 11 (3.0)

Slide 35

Slide 35 text

android:enterFadeDuration="..."
 android:exitFadeDuration="..." • drawables • Animates between selector states 11 (3.0)

Slide 36

Slide 36 text

MORE COMPLEX

Slide 37

Slide 37 text

ObjectAnimator Honeycomb (3.0+)

Slide 38

Slide 38 text

FEATURES • Duration • Value interpolator • Sets • Sequentially • Parallel (“Together”) • Listeners • Repetition • Animate any target (Object)

Slide 39

Slide 39 text

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)

Slide 40

Slide 40 text

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)

Slide 41

Slide 41 text

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)

Slide 42

Slide 42 text

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)

Slide 43

Slide 43 text

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();

Slide 44

Slide 44 text

ViewPropertyAnimator Honeycomb MR1 (3.1+)

Slide 45

Slide 45 text

FEATURES • Duration • Value interpolator • Listeners • Start delay • Fluent interface

Slide 46

Slide 46 text

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)

Slide 47

Slide 47 text

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)

Slide 48

Slide 48 text

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)

Slide 49

Slide 49 text

A LITTLE MORE ON INTERPOLATORS

Slide 50

Slide 50 text

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…

Slide 51

Slide 51 text

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

Slide 52

Slide 52 text

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

Slide 53

Slide 53 text

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

Slide 54

Slide 54 text

TIPS, TRICKS, AND GOTCHAS

Slide 55

Slide 55 text

X/Y ROTATION Bad

Slide 56

Slide 56 text

• View#setCameraDistance(float) for rotationX/ rotationY

Slide 57

Slide 57 text

X/Y ROTATION Good

Slide 58

Slide 58 text

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)

Slide 59

Slide 59 text

VIEW CLIPPING What you want What you’ve got

Slide 60

Slide 60 text

VIEW CLIPPING • Parent view encapsulates child drawing • Can’t draw outside • Refactor your layout

Slide 61

Slide 61 text

AGAIN What you want What you’ve got

Slide 62

Slide 62 text

WHAT YOU’VE GOT

Slide 63

Slide 63 text

WHAT YOU WANT

Slide 64

Slide 64 text

VIEWOVERLAY • Could also use ViewOverlay • View.getOverlay().addView(myView); • Remove from parent first! 18 (4.3)

Slide 65

Slide 65 text

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

Slide 66

Slide 66 text

VIEW COMPOSITING

Slide 67

Slide 67 text

VIEW COMPOSITING What you want What you’ve got

Slide 68

Slide 68 text

VIEW COMPOSITING • Use a TextureView instead • Only for animations/movement use cases 14 (4.0)

Slide 69

Slide 69 text

BACKWARD COMPATIBILITY

Slide 70

Slide 70 text

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

Slide 71

Slide 71 text

HOMEWORK

Slide 72

Slide 72 text

TRANSITIONMANAGER • Manages animations between layouts • Compatibility library/libraries already in the works 18 (4.3)

Slide 73

Slide 73 text

MATERIAL & L • New hotness • Ripple • Reveal • Hero • Curved motion • View state changes L (?)

Slide 74

Slide 74 text

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

Slide 75

Slide 75 text

GO OUT AND ANIMATE

Slide 76

Slide 76 text

THANKS Purple shirts seem to be a theme @DallasGutauckis /+DallasGutauckis Praise be to Duarte