A medium-length version of a talk I gave about Android animations at mdevcon in Amsterdam 2014.
Keynote version: http://goo.gl/7KuSxP
I Can Animate and SoCan YouDaniel Lew, Mar. 8, 2014
View Slide
Typical AnimationDemo
What Can Be Done
Revelations
Revelation #1Every animation is unique
Revelation #2Animation code is not pretty
Revelation #3Animations firstAnimate
Revelation #4Animate for 4.x+
Ditch 2.x• Poor performance • Can't use modern tricks • Backup: NineOldAndroids
Ditch 3.x• Tiny userbase • ViewPropertyAnimator -Introduced 3.1 • TextureView -Introduced 4.0
Building Animations• Figure out whatattributes to animate • Design View hierarchy • Measure attribute start/end values • Setup and run animators
Determining Attributes• Alpha - every element • Translate - every row • Translate - detailsheader/footer • Scale - details rows (ahardcore fake) • Fading background - notneeded!
View Hierarchy• Animation informs Viewhierarchy • Here, rows gounderneath split actionbar
Measuring Views• Problem: Views not measured untilsometime after inflation • ViewTreeObserver - lets you know when aView has been measured • Two options: OnGlobalLayoutListener,OnPreDrawListener
ViewTreeObserverPattern!final View view = findViewById(R.id.view);view.getViewTreeObserver().addOnPreDrawListener(newOnPreDrawListener() {public boolean onPreDraw() {view.getViewTreeObserver().removeOnPreDrawListener(this);// Measure here!return true;}});
Measuring "After"• Align to other existing Views • Create invisible "dummy" Views to animatetowards
Running Animators• ObjectAnimator - animate! • AnimatorSet - synchronize multipleAnimators • AnimatorListener - setup and cleanup • Canceling Animators w/ reverse()
Property Animators• Generic animation framework • Animates *any* value over time • Basic building block for most animations
ObjectAnimator• Type of property animator • Used for animating essential View properties • Position (or translation) • Rotation • Scale • Alpha • Can be used on custom View properties
ObjectAnimator// Uses setAlpha() and getAlpha() to animateObjectAnimator.ofFloat(myView, "alpha", 0, 1).start();!!!// Uses built-in property to avoid reflectionObjectAnimator.ofFloat(myView, View.ALPHA, 1).start();
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();
Animator Listeners!ObjectAnimator anim = ObjectAnimator.ofFloat(view,"alpha", 1);anim.addListener(new AnimatorListenerAdapter() {public void onAnimationEnd(Animator animation) {// Clean-up code here}});anim.start();
Reversing Course• ValueAnimator.reverse() • Useful for smoothly canceling an animator • Can recursively traverse AnimatorSet forValueAnimators
Questions So Far?
Performance• Choppy animation == painful • Performance cannot be an afterthought • Smooth animations informs structure
PerformanceBreakdown• Layout - size/location of Views • Draw - what's inside Views • Render - pushing it on screen
Layout Performance• Initiated byView.requestLayout() • Slow - avoid at all costs • Can sneak up on you
Draw Performance• Initiated byView.invalidate() • How animations are run
Render Performance• Initiated every timepixels are put on screen • Varies with pixel count/speed of device • Try to reduce overdraw
Profiling
Profile GPU Rendering• Blue - Draw • Red - Process • Orange - Execute • Green line - your goal
Show GPU Overdraw• Shows overdrawn pixels • Best to worst: nothing,blue, green, red, dark red • Some overdrawnecessary, but reduce ifpossible
Other Profilers• Traceview - Breakdown of method calls • Systrace - Measures everything on system • OpenGL Traces - Every single OpenGL call
Profile Warnings• Profilers can be inaccurate • One profiling tool at a time, please • Profile multiple devices
Optimization: Layers• Layers store drawnViews for reuse • Reduces drawing duringanimation • Reduces overdrawduring animation
LayersLinearLayoutImageView TextView TextView
LayersLinearLayoutImageView TextView TextViewLinearLayout
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();
Layer Caveats• Warning: redrawing alayer is *slower* thannon-layer • DisplayLists will rebuildlayers when necessary • Layering simple Viewsjust hurts performance
Other Animation Tools
Custom Views• Custom Views easierthan they sound! • Animate your ownattributes • Simplify animation viaisolation • Cheat for performance’ssake
set directions• View methods: setLeft(),setRight(), setTop(),setBottom() • Change layout withoutrequesting layout! • Parent layout blowsaway values, may have toblock
Drawable Animations• AnimationDrawable - frame animations • Custom animated Drawable in a View • Drawable.setCallback() • View.verifyDrawable()
SurfaceView andTextureView• Great for constantlyanimated View • SurfaceView is fast but isweird • TextureView is 4.0+, butcan be moved around
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)
Thank You!• Blog: http://blog.danlew.net • Movies App Source: http://goo.gl/WiRTlQ • Twitter: @danlew42