Slide 1

Slide 1 text

Material Animations and other related stories

Slide 2

Slide 2 text

Agenda • How Android draws • Why 60 fps? • Shadows • Animations • Activity Transitions • Performance tools #perfmatters

Slide 3

Slide 3 text

+DavidGonzalezMalmstein malmstein David González Technical Product Owner at Novoda @dggonzalez Google Developer Expert for Android

Slide 4

Slide 4 text

4

Slide 5

Slide 5 text

How Android draws 5

Slide 6

Slide 6 text

Rasterization 6

Slide 7

Slide 7 text

7 SCREEN GPU Rasterization CPU Polygons Textures Expensive Expensive

Slide 8

Slide 8 text

Why 60 fps? 8

Slide 9

Slide 9 text

9 http://www.techverticals.com/wp-content/uploads/2012/04/24fps-vs-30fps-vs-60fps.jpg

Slide 10

Slide 10 text

Design vs Performance 10 1000ms / 60 frames = 16.666 ms / frame

Slide 11

Slide 11 text

Overdraw

Slide 12

Slide 12 text

Overdraw

Slide 13

Slide 13 text

Shadows 13 • Views with elevation casts showdown onto background • Orthographic projection • Animated like other View properties

Slide 14

Slide 14 text

No content

Slide 15

Slide 15 text

Shadows 15

Slide 16

Slide 16 text

Elevation

Slide 17

Slide 17 text

Outline 17 
 res/drawable/myrect.xml res/layout/fragment_sample.xml

Slide 18

Slide 18 text

18 static class OvalOutlineProvider extends ViewOutlineProvider{ @Override
 public void getOutline(View view, Outline outline) { outline.setOval(0, 0, view.getWidth(), view.getHeight(), 10); } } OvalOutlineProvider.java

Slide 19

Slide 19 text

Define your own one view.setClipToOutline(true);
 view.setOutlineProvider(new RoundRectOutlineProvider()); MyFragment.java

Slide 20

Slide 20 text

Basic elevation 20

Slide 21

Slide 21 text

21 res/layout/elevation_basic.xml

Slide 22

Slide 22 text

22 ElevationBasicFragment.java shape2.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View view, MotionEvent motionEvent) { int action = motionEvent.getActionMasked(); switch (action) { case MotionEvent.ACTION_DOWN: view.animate().setDuration(100) .scaleX(1.2f).scaleY(1.3f).translationZ(120); break; case MotionEvent.ACTION_UP: view.animate().setDuration(100) .scaleX(1).scaleY(1).translationZ(0); break; default: return false; } return true; } });

Slide 23

Slide 23 text

Drag elevation 23

Slide 24

Slide 24 text

24 res/layout/elevation_drag.xml

Slide 25

Slide 25 text

25 ElevationDragFragment.java /* Raise the circle in z when the "z+" button is clicked. */ rootView.findViewById(R.id.raise_bt).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mElevation += mElevationStep; floatingShape.setElevation(mElevation); } }); /* Lower the circle in z when the "z-" button is clicked. */ rootView.findViewById(R.id.lower_bt).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mElevation -= mElevationStep; // Don't allow for negative values of Z. if (mElevation < 0) { mElevation = 0; } } });

Slide 26

Slide 26 text

26 ElevationDragFragment.java dragLayout.setDragFrameController(new DragFrameLayout.DragFrameLayoutController() { @Override public void onDragDrop(boolean captured) { /* Animate the translation of the {@link View}. Note that the translation is being modified, not the elevation. */ floatingShape.animate() .translationZ(captured ? 50 : 0) .scaleX(1.2f) .scaleY(1.3f) .setDuration(100); Log.d(TAG, captured ? "Drag" : "Drop"); } });

Slide 27

Slide 27 text

Animations 27

Slide 28

Slide 28 text

Animation curves 28

Slide 29

Slide 29 text

Path Interpolator 29 res/interpolator/linear.xml

Slide 30

Slide 30 text

Path Interpolator 30 res/interpolator/fast_out_linear_in.xml

Slide 31

Slide 31 text

Path Interpolator 31 res/interpolator/fast_out_slow_in.xml

Slide 32

Slide 32 text

Path Interpolator 32 res/interpolator/linear_out_slow_in.xml

Slide 33

Slide 33 text

33 InterpolatorFragment.java // Path for 'in' animation: growing from 20% to 100% mPathIn = new Path(); mPathIn.moveTo(0.2f, 0.2f); mPathIn.lineTo(1f, 1f); // Path for 'out' animation: shrinking from 100% to 20% mPathOut = new Path(); mPathOut.moveTo(1f, 1f); mPathOut.lineTo(0.2f, 0.2f); ObjectAnimator animator = ObjectAnimator.ofFloat(mView, View.SCALE_X, View.SCALE_Y, path); // Set the duration and interpolator for this animation animator.setDuration(duration); animator.setInterpolator(interpolator); animator.start();

Slide 34

Slide 34 text

The Interpolator party! 34

Slide 35

Slide 35 text

Touch feedback

Slide 36

Slide 36 text

36 res/drawable/mystatedrawable.xml

Slide 37

Slide 37 text

Touch feedback Render Thread

Slide 38

Slide 38 text

Reveal effect Animator anim = ViewAnimationUtils. createCircularReveal( myView, centerX, centerY, startRadius, finalRadius); 
 anim.start(); MyActivity.java

Slide 39

Slide 39 text

MyActivity.java final View myView = findViewById(R.id.my_view); Animator anim = ViewAnimationUtils.createCircularReveal(myView, cx, cy, initialRadius, 0); anim.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { super.onAnimationEnd(animation); myView.setVisibility(View.INVISIBLE); } }); anim.start();

Slide 40

Slide 40 text

Activity transitions 40 • Window Transitions animate windows • Activity transitions animate window components • Animate when launching one activity from another • Shared elements are transferred via ActivityOptions • Based on the Transitions API released with KitKat

Slide 41

Slide 41 text

Enable transitions 41 getWindow(). requestFeature(Window.FEATURE_CONTENT_TRANSITIONS); <!-- enable window content transitions --> <item name="android:windowContentTransitions">true</item> res/values/theme.xml MainActivity.java

Slide 42

Slide 42 text

Activity transition 42 <!-- specify enter and exit transitions --> <item name=“android:windowEnterTransition"> @transition/explode</item> <item name=“android:windowExitTransition”> @transition/explode</item> res/values/theme.xml

Slide 43

Slide 43 text

Example 43

Slide 44

Slide 44 text

Activity A 44 res/layout/grid_item.xml

Slide 45

Slide 45 text

Activity B 45 res/layout/detail.xml

Slide 46

Slide 46 text

46 TransitionActivity.java ActivityOptionsCompat activityOptions = ActivityOptionsCompat.makeSceneTransitionAnimation( this, new Pair(view.findViewById(R.id.imageview_item), DetailActivity.VIEW_NAME_HEADER_IMAGE), new Pair(view.findViewById(R.id.textview_name), DetailActivity.VIEW_NAME_HEADER_TITLE)); // Now we can start the Activity, providing the activity options as a bundle ActivityCompat.startActivity(this, intent, activityOptions.toBundle());

Slide 47

Slide 47 text

47 DetailActivity.java @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_transition_details); /** * Set the name of the view's which will be transition to, using the static values above. * This could be done in the layout XML, but exposing it via static variables allows easy * querying from other Activities */ ViewCompat.setTransitionName(mHeaderImageView, VIEW_NAME_HEADER_IMAGE); ViewCompat.setTransitionName(mHeaderTitle, VIEW_NAME_HEADER_TITLE); }

Slide 48

Slide 48 text

Shared element transition 48 res/transition/grid_detail_transition.xml res/layout/fragment_sample.xml

Slide 49

Slide 49 text

Sync Transitions and animations 49

Slide 50

Slide 50 text

50 DetailActivity.java getWindow().getEnterTransition().addListener(new Transition.TransitionListener() { @Override public void onTransitionEnd(Transition transition) { mFab.animate() .translationY(0) .setInterpolator(new OvershootInterpolator(1.f)) .setStartDelay(300) .setDuration(400) .start(); } });

Slide 51

Slide 51 text

Animate before transition 51

Slide 52

Slide 52 text

Animate before transition 52 @Override public void onBackPressed() { mFab.animate() .translationYBy(2 * 56) .setInterpolator(new OvershootInterpolator(1.f)) .setDuration(400) .withEndAction(new Runnable() { @Override public void run() { finishAfterTransition(); } }); } DetailActivity.java

Slide 53

Slide 53 text

Performance tools 53

Slide 54

Slide 54 text

Profile GPU Rendering 54

Slide 55

Slide 55 text

Show GPU Overdraw 55

Slide 56

Slide 56 text

Hierarchy Viewer 56

Slide 57

Slide 57 text

Traceview 57

Slide 58

Slide 58 text

MaterialAnimations Fork me! Examples of animations and transitions http://github.com/malmstein/MaterialAnimations 58

Slide 59

Slide 59 text

@dggonzalez +DavidGonzalezMalmstein malmstein Thank you! Questions?