Material Animations: show me the code!

Material Animations: show me the code!

- Why animate?
- Good animation samples
- Available tools to animate
- Transition Framework
- Activity transitions
- Shared element transitions
- View property animations
- Complex animations
- Circular Reveal

> Animated slides

https://www.youtube.com/watch?v=5e1Yh0fSZhQ

> Resources

Material Animations: Code Samples

https://github.com/lgvalle/Material-Animations

Alex Lockwood: Transition Framework
http://goo.gl/y4ZSsp

Saul Molinero: User interface
http://goo.gl/8gex9n

Chris Basha: Overhauling the Twitter Experience on Android

https://goo.gl/F281b2

Material Witness: How Android material applications work

https://youtu.be/97SWYiRtF0Y

Pasquale D’Silva: Designing with animation

https://youtu.be/TMe0WnkF1Lc

8897931773317248080248df1250a8ea?s=128

Luis G. Valle

October 02, 2015
Tweet

Transcript

  1. Material Animations Show me the code! @lgvalle lgvalle.xyz

  2. Why animate?

  3. Animations teach what is happening · what can i do

  4. Where things go? What can I do? Where am I?

    Where things come from?
  5. https://medium.com/@BashaChris/overhauling-the-twitter-experience-on-android-80f5b09e7c67 Overhauling the Twitter Experience on Android Where things come

    Where things go? Where am I? What can I do?
  6. Where things come Where things go? Where am I? What

    can I do?
  7. Where things come Where things go? Where am I? What

    can I do?
  8. Where things come Where things go? Where am I? What

    can I do?
  9. Where things come Where things go? Where am I? What

    can I do?
  10. What can be animated? Layout content Shared elements View Properties

    x
  11. Property Animation System
 (API 11) View property changes Transition Framework


    (API 19) View property changes Layout changes ViewAnimationUtils
 (API 21) CircularReveal Activity Transitions Fragment Transitions
  12. Animate screen transitions exit · enter · shared startActivity(B) A

    Exit Enter A B B … B Return Reenter B A A … back()
  13. startActivity(B) A Exit Enter A B B … B Return

    Reenter B A A … back() Cross-fade by default Reversed enter/exit by default
  14. startActivity(B) A Exit Enter A B B … B Return

    Reenter B A A … back() But you can customise! Cross-fade by default Reversed enter/exit by default
  15. Explode Slide Fade Transition custom effects

  16. > activities/MainActivity.java @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);


    Explode explode = new Explode();
 getWindow().setExitTransition(explode); }
 Exit Transition @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_details);
 }
 > activities/DetailsActivity.java
  17. startActivity(B) A Exit Enter A B B … B Return

    Reenter B A A … back() A B B A Enter and Exit animations 
 overlap each other Transition Overlap
  18. startActivity(B) A Exit Enter A B B … B Return

    Reenter B A A … back() A B B A Enter and Exit animations 
 overlap each other Transition Overlap
  19. protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 Explode explode =

    new Explode();
 getWindow().setExitTransition(explode); }
 Disable overlap @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_details); 
 getWindow().setAllowEnterTransitionOverlap(false);
 } 
 > activities/DetailsActivity.java
  20. > activities/MainActivity.java @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);


    Explode explode = new Explode(); explode.excludeTarget(R.id.toolbar, true);
 getWindow().setExitTransition(explode); }
 Exclude Views @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout. getWindow().setAllowEnterTransitionOverlap(false); } 
 > activities/
  21. protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 Explode explode =

    new Explode(); explode.excludeTarget(R.id.toolbar, true); getWindow().setExitTransition(explode); }
 Return Transition @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_details); getWindow().setAllowEnterTransitionOverlap(false); Slide slide = new Slide(Gravity.RIGHT);
 getWindow().setReturnTransition(slide);
 } 
 > activities/DetailsActivity.java
  22. Shared Element Transition startActivity(B) A Exit Enter A B B

    … B Return Reenter B A A … back() Shared Element Shared Element 
 has its own transitions
  23. res/values/styles.xml <style name=“MaterialAnimations.Main"> <item name=“android:windowContentTransitions”>true</item> … </style> 1. Enable content

    transition activities/MainActivity.java @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState); getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
 … }
 -OR-
  24. <CardView android:id=“@+id/rowView”
 android:transitionName=“rowName”/>
 <CardView android:id=“@+id/detailView”
 android:transitionName=“rowName”/>
 2. Common Transition Name

  25. > activities/MainActivity.java Intent i = new Intent(this, DetailsActivity.class);
 
 ActivityOptions

    options = ActivityOptions .makeSceneTransitionAnimation( this, rowView, // shared element view "rowName"); // common transition name 
 startActivity(i, options.toBundle());
 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout. getWindow().setAllowEnterTransitionOverlap(false); } 
 > activities/ 3. Start Activity (with options)
  26. > activities/DetailsActivity.java Transition fade = getWindow().getEnterTransition();
 fade.addListener(new TransitionListener() {
 @Override


    public void onTransitionEnd(Transition t) {
 fab.setVisibility(View.VISIBLE); fade.removeListener(this);
 } …
 }); Transition listener
  27. > activities/DetailsActivity.java Transition fade = getWindow().getEnterTransition();
 fade.addListener(new TransitionListener() {
 @Override


    public void onTransitionEnd(Transition t) {
 fab.setVisibility(View.VISIBLE); fade.removeListener(this);
 } …
 }); Transition listener Don’t forget!
  28. > activities/DetailsActivity.java Transition fade = getWindow().getEnterTransition();
 fade.addListener(new TransitionListener() {
 @Override


    public void onTransitionEnd(Transition t) {
 fab.setVisibility(View.VISIBLE); fade.removeListener(this); } …
 }); Transition listener @Override
 public void onBackPressed() {
 fab.setVisibility(View.INVISIBLE);
 finishAfterTransition(); }
  29. Animate screen elements property changes · circular reveal

  30. > activities/DetailsActivity.java Transition fade = getWindow().getEnterTransition();
 fade.addListener(new TransitionListener() {
 @Override


    public void onTransitionEnd(Transition t) {
 fab.animate().scaleX(1f).scaleY(1f) fade.removeListener(this); } …
 }); Transition listener @Override
 public void onBackPressed() {
 fab.animate().scaleX(0f).scaleY(0f)
 .withEndAction(new Runnable() {
 @Override
 public void run() {
 finishAfterTransition();
 }
 }); }
  31. > activities/DetailsActivity.java Transition fade = getWindow().getEnterTransition();
 fade.addListener(new TransitionListener() {
 @Override


    public void onTransitionEnd(Transition t) {
 fab.animate().scaleX(1f).scaleY(1f) fade.removeListener(this); } …
 }); Transition listener @Override
 public void onBackPressed() {
 fab.animate().scaleX(0f).scaleY(0f)
 .withEndAction(new Runnable() {
 @Override
 public void run() {
 finishAfterTransition();
 }
 }); } Property Animation System
 (API 11+)
  32. What about complex animations?

  33. TransitionManager.beginDelayedTransition StartTransition

  34. StartTransition Save Start State TransitionManager.beginDelayedTransition

  35. StartTransition Capture end state Save Start State TransitionManager.beginDelayedTransition

  36. StartTransition Capture end state Animate difference Save Start State TransitionManager.beginDelayedTransition

  37. public void onClickFab() { int transitionId = R.transition.changebounds_with_arcmotion;
 TransitionInflater inflater

    = TransitionInflater.from(this); Transition transition = inflater.inflateTransition(transitionId); 
 TransitionManager.beginDelayedTransition(viewRoot, transition);
 RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams( RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
 layoutParams.addRule(RelativeLayout.CENTER_HORIZONTAL);
 layoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
 fab.setLayoutParams(layoutParams) } FAB Transition
  38. int transitionId = R.transition.changebounds_with_arcmotion;
 TransitionInflater inflater = TransitionInflater.from(this); Transition transition

    = inflater.inflateTransition(transitionId); 
 TransitionManager.beginDelayedTransition(viewRoot, transition);
 RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams( RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT); 
 layoutParams.addRule(RelativeLayout.CENTER_HORIZONTAL);
 layoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
 fab.setLayoutParams(layoutParams); FAB Transition Inflate transition from XML!
  39. <?xml version="1.0" encoding="utf-8"?>
 <changeBounds 
 android:duration="@integer/anim_duration_long"
 android:interpolator="@android:interpolator/decelerate_cubic">
 <arcMotion
 android:maximumAngle="45"
 android:minimumHorizontalAngle="90"


    android:minimumVerticalAngle="0" />
 
 </changeBounds> > res/transitions/changebounds_with_arcmotion.xml
  40. int transitionId = R.transition.changebounds_with_arcmotion;
 TransitionInflater inflater = TransitionInflater.from(this); Transition transition

    = inflater.inflateTransition(transitionId); 
 TransitionManager.beginDelayedTransition(viewRoot, transition);
 RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams( RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT); 
 layoutParams.addRule(RelativeLayout.CENTER_HORIZONTAL);
 layoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
 fab.setLayoutParams(layoutParams); FAB Transition
  41. int transitionId = R.transition.changebounds_with_arcmotion;
 TransitionInflater inflater = TransitionInflater.from(this); Transition transition

    = inflater.inflateTransition(transitionId); 
 TransitionManager.beginDelayedTransition(viewRoot, transition);
 RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams( RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
 layoutParams.addRule(RelativeLayout.CENTER_HORIZONTAL);
 layoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
 fab.setLayoutParams(layoutParams); FAB Transition
  42. int transitionId = R.transition.changebounds_with_arcmotion;
 TransitionInflater inflater = TransitionInflater.from(this); Transition transition

    = inflater.inflateTransition(transitionId); 
 TransitionManager.beginDelayedTransition(viewRoot, transition);
 RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams( RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
 layoutParams.addRule(RelativeLayout.CENTER_HORIZONTAL);
 layoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
 fab.setLayoutParams(layoutParams); FAB Transition
  43. int transitionId = R.transition.changebounds_with_arcmotion;
 TransitionInflater inflater = TransitionInflater.from(this); Transition transition

    = inflater.inflateTransition(transitionId); 
 TransitionManager.beginDelayedTransition(viewRoot, transition);
 RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams( RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
 layoutParams.addRule(RelativeLayout.CENTER_HORIZONTAL);
 layoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
 fab.setLayoutParams(layoutParams); FAB Transition Where is the Circular Reveal?!
  44. Circular Reveal Title A Title A Title A Title B

    Bacon ipsum dolor amet sausage bacon pork chop strip steak cow porchetta landjaeger ham sirloin swine leberkas prosciutto turducken ball tip. Pork chop kielbasa shank cow, pig corned beef hamburger
  45. Circular Reveal (x,y) x = (left + right) / 2


    y = (top + bottom) / 2 
 startRadius = 0
 endRadius = max(width, height)
 createCircularReveal(view, x, y, startRadius, endRadius) left right top bottom
  46. int x = (view.getLeft() + view.getRight()) / 2;
 int y

    = (view.getTop() + view.getBottom()) / 2;
 int startRadius = 0; int endRadius = Math.max(view.getWidth(), view.getHeight()); 
 Animator anim = ViewAnimationUtils .createCircularReveal(view, x, y, startRadius, endRadius); view.setVisibility(View.VISIBLE); anim.start(); Circular Reveal (x,y) left right top bottom
  47. int transitionId = R.transition.changebounds_with_arcmotion;
 TransitionInflater inflater = TransitionInflater.from(this); Transition transition

    = inflater.inflateTransition(transitionId); transition.addListener(new Transition.TransitionListener() {
 @Override
 public void onTransitionEnd(Transition transition) {
 fab.setVisibility(View.GONE);
 createRevealForView(extraContent);
 }
 });
 (…) private Animator createRevealForView(ViewGroup view) {
 int x = (view.getLeft() + view.getRight()) / 2;
 int y = view.getBottom();
 float finalRadius = (float) Math.max(view.getWidth(), view.getHeight());
 
 Animator anim = ViewAnimationUtils.createCircularReveal(view, x, y, 0, finalRadius);
 viewRoot.setVisibility(View.VISIBLE);
 anim.start();
 } Circular Reveal
  48. -Shared element Transition -Transition Listener -Enter / Exit Transition -Property

    Animation System -Delayed Transitions -Circular Reveal
  49. Pasquale D’Silva: Designing with animation
 https://youtu.be/TMe0WnkF1Lc Material Animations: Code Samples


    https://github.com/lgvalle/Material-Animations Alex Lockwood: Transition Framework
 http://goo.gl/y4ZSsp Saul Molinero: User interface 
 http://goo.gl/8gex9n Material Witness: How Android material applications work
 https://youtu.be/97SWYiRtF0Y Chris Basha: Overhauling the Twitter Experience on Android
 https://goo.gl/F281b2 Resources
  50. Questions? @lgvalle lgvalle.xyz