Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Material Animations: show me the code! (Codemotion 2015)

Material Animations: show me the code! (Codemotion 2015)

** Codemotion Madrid 2015 **

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

> 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

Luis G. Valle

November 27, 2015
Tweet

More Decks by Luis G. Valle

Other Decks in Programming

Transcript

  1. Property Animation System
 (API 12) View property changes Transition Framework


    (API 19) View property changes Layout changes ViewAnimationUtils
 (API 21) CircularReveal Activity Transitions Fragment Transitions How can we animate?
  2. Property Animation System (API 12) View property changes Transition Framework


    (API 19) View property changes Layout changes ViewAnimationUtils (API 21) CircularReveal Activity Transitions Fragment Transitions How can we animate?
  3. Animate screen transitions exit · enter · shared startActivity(B) A

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

    Return
 Transition Reenter
 Transition B A A back()
  5. startActivity(B) A Exit Transition Enter
 Transition A B B B

    Return
 Transition Reenter
 Transition B A A Default: 
 Cross-fade back() Default: 
 Reversed enter/exit
  6. startActivity(B) A Exit Transition Enter
 Transition A B B B

    Return
 Transition Reenter
 Transition B A A Default: 
 Cross-fade back() Default: 
 Reversed enter/exit But you can customise!
  7. startActivity(B) A Exit Transition Enter
 Transition A B B B

    Return
 Transition Reenter
 Transition B A A back()
  8. startActivity(B) A Exit Transition Enter
 Transition A B B B

    Return
 Transition Reenter
 Transition B A A back()
  9. > activities/Activity_A.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/Activity_B.java
  10. > activities/Activity_A.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/Activity_B.java
  11. startActivity(B) A Exit Transition Enter
 Transition A B B B

    Return
 Transition Reenter
 Transition B A A back()
  12. startActivity(B) A Exit Transition Enter
 Transition A B B B

    Return
 Transition Reenter
 Transition B A A back() Default:
 Transitions 
 Overlap
  13. > activities/Activity_A.java @Override
 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);
 }
 > activities/Activity_B.java
  14. > activities/Activity_A.java @Override
 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/Activity_B.java
  15. > activities/Activity_A.java @Override
 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/Activity_B.java
  16. > activities/Activity_A.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.activity_details);
 getWindow().setAllowEnterTransitionOverlap(false);
 }
 > activities/Activity_B.java
  17. > activities/Activity_A.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.activity_details);
 getWindow().setAllowEnterTransitionOverlap(false);
 }
 > activities/Activity_B.java
  18. startActivity(B) A Exit Transition Enter
 Transition A B B B

    Return
 Transition Reenter
 Transition B A A back()
  19. startActivity(B) A Exit Transition Enter
 Transition A B B B

    Return
 Transition Reenter
 Transition B A A back()
  20. > activities/Activity_A.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); }
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_details);
 getWindow().setAllowEnterTransitionOverlap(false);
 }
 > activities/Activity_B.java Return Transition
  21. > activities/Activity_A.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); }
 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/Activity_B.java
  22. startActivity(B) A Exit Transition Enter
 Transition A B B B

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

    content transition activities/Activity_A.java @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState); getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
 … }
 -OR-
  24. > activities/Activity_A.java Intent i = new Intent(this, Activity_B.class);
 
 ActivityOptions

    options = ActivityOptions .makeSceneTransitionAnimation( this, rowView, // shared element view "rowName"); // common transition name 
 startActivity(i, options.toBundle());
 3. Start Activity (with options)
  25. startActivity(B) A Exit Transition Enter
 Transition A B B B

    Return
 Transition Reenter
 Transition B A A back() Transition Listener Transition Listener
  26. Transition Listener > activities/Activity_B.java 
 @Override
 protected void onCreate(Bundle savedInstanceState)

    {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_details);
 getWindow().setAllowEnterTransitionOverlap(false);
 
 }

  27. Transition Listener > activities/Activity_B.java 
 @Override
 protected void onCreate(Bundle savedInstanceState)

    {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_details);
 getWindow().setAllowEnterTransitionOverlap(false);
 
 getWindow().getEnterTransition() .addListener(new TransitionListener() {
 @Override
 public void onTransitionEnd(Transition t) {
 fab.setVisibility(View.VISIBLE); fade.removeListener(this);
 } …
 });
 }
 Don’t forget!
  28. Transition Listener > activities/Activity_B.java 
 @Override
 protected void onCreate(Bundle savedInstanceState)

    {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_details);
 getWindow().setAllowEnterTransitionOverlap(false);
 
 getWindow().getEnterTransition() .addListener(new TransitionListener() {
 @Override
 public void onTransitionEnd(Transition t) {
 fab.setVisibility(View.VISIBLE); fade.removeListener(this);
 } …
 });
 }
 @Override
 public void onBackPressed() {
 fab.setVisibility(View.INVISIBLE);
 finishAfterTransition(); }
  29. > activities/Activity_B.java Transition fade = getWindow().getEnterTransition();
 fade.addListener(new TransitionListener() {
 public

    void onTransitionEnd(Transition t) {
 fab.setVisibility(View.VISIBLE); fade.removeListener(this); }
 }); public void onBackPressed() {
 fab.setVisibility(View.INVISIBLE);
 finishAfterTransition(); } (API 12+) Property animation system
  30. > activities/Activity_B.java Transition fade = getWindow().getEnterTransition();
 fade.addListener(new TransitionListener() {
 public

    void onTransitionEnd(Transition t) {
 fab.animate() .scaleX(1f) .scaleY(1f) fade.removeListener(this); }
 }); public void onBackPressed() {
 fab.animate() .scaleX(0f) .scaleY(0f)
 .withEndAction(new Runnable() {
 @Override
 public void run() {
 finishAfterTransition();
 }
 }); } (API 12+) Property animation system
  31. > activities/Activity_B.java Transition fade = getWindow().getEnterTransition();
 fade.addListener(new TransitionListener() {
 public

    void onTransitionEnd(Transition t) {
 fab.animate() .scaleX(1f) .scaleY(1f) fade.removeListener(this); }
 }); public void onBackPressed() {
 fab.animate() .scaleX(0f) .scaleY(0f)
 .withEndAction(new Runnable() {
 @Override
 public void run() {
 finishAfterTransition();
 }
 }); } (API 12+) Property animation system
  32. public void onClickFab() { Transition transition = TransitionInflater.from(this) .inflateTransition(R.transition.changebounds_with_arcmotion); TransitionManager

    .beginDelayedTransition(viewRoot, transition);
 fab.setLayoutParams( new RelativeLayout.LayoutParams( WRAP_CONTENT, WRAP_CONTENT, CENTER_HORIZONTAL, ALIGN_PARENT_BOTTOM) ); } Fab Transition
  33. public void onClickFab() { Transition transition = TransitionInflater.from(this) .inflateTransition(R.transition.changebounds_with_arcmotion); TransitionManager

    .beginDelayedTransition(viewRoot, transition);
 fab.setLayoutParams( new RelativeLayout.LayoutParams( WRAP_CONTENT, WRAP_CONTENT, CENTER_HORIZONTAL, ALIGN_PARENT_BOTTOM) ); } Fab Transition Inflate transition from XML!
  34. public void onClickFab() { Transition transition = TransitionInflater.from(this) .inflateTransition(R.transition.changebounds_with_arcmotion); TransitionManager

    .beginDelayedTransition(viewRoot, transition);
 fab.setLayoutParams( new RelativeLayout.LayoutParams( WRAP_CONTENT, WRAP_CONTENT, CENTER_HORIZONTAL, ALIGN_PARENT_BOTTOM) ); } Fab Transition
  35. public void onClickFab() { Transition transition = TransitionInflater.from(this) .inflateTransition(R.transition.changebounds_with_arcmotion); TransitionManager

    .beginDelayedTransition(viewRoot, transition);
 fab.setLayoutParams( new RelativeLayout.LayoutParams( WRAP_CONTENT, WRAP_CONTENT, CENTER_HORIZONTAL, ALIGN_PARENT_BOTTOM) ); } Fab Transition
  36. public void onClickFab() { Transition transition = TransitionInflater.from(this) .inflateTransition(R.transition.changebounds_with_arcmotion); TransitionManager

    .beginDelayedTransition(viewRoot, transition);
 fab.setLayoutParams( new RelativeLayout.LayoutParams( WRAP_CONTENT, WRAP_CONTENT, CENTER_HORIZONTAL, ALIGN_PARENT_BOTTOM) ); } Fab Transition Where is the Circular Reveal?!
  37. 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 Circular Reveal Animation
  38. Circular Reveal Animation int x = (view.getLeft() + view.getRight()) /

    2;
 int y = (view.getTop() + view.getBottom()) / 2;
 int startRadius = 0; int endRadius = Math.hypot(x, y); 
 Animator anim = ViewAnimationUtils .createCircularReveal( view, 
 x, y, startRadius, endRadius); view.setVisibility(View.VISIBLE); anim.start(); (x,y) left right top bottom hypot
  39. (…) transition.addListener(new Transition.TransitionListener() {
 @Override
 public void onTransitionEnd(Transition transition) {


    fab.setVisibility(View.GONE);
 createRevealForView(extraContent);
 }
 }); private Animator createRevealForView(ViewGroup view) { int x = (viewRoot.getLeft() + viewRoot.getRight()) / 2;
 int y = viewRoot.getBottom() - fab.getHeight();
 float finalRadius = (float) Math.hypot(x, y);
 
 Animator anim = ViewAnimationUtils .createCircularReveal(viewRoot, x, y, fab.getWidth(), finalRadius); viewRoot.setVisibility(View.VISIBLE);
 anim.start();
 } Circular Reveal Animation
  40. - Shared element Transition - Transition Listener - Enter /

    Exit Transition - Property Animation System - Transition Manager - Circular Reveal
  41. 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