$30 off During Our Annual Pro Sale. View Details »

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

Luis G. Valle

October 02, 2015
Tweet

More Decks by Luis G. Valle

Other Decks in Technology

Transcript

  1. 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
  2. Animate screen transitions exit · enter · shared startActivity(B) A

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

    Reenter B A A … back() Cross-fade by default Reversed enter/exit by default
  4. 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
  5. > 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
  6. 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
  7. 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
  8. 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
  9. > 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/
  10. 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
  11. 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
  12. 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-
  13. > 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)
  14. > 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
  15. > 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!
  16. > 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(); }
  17. > 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();
 }
 }); }
  18. > 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+)
  19. 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
  20. 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!
  21. 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
  22. 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
  23. 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
  24. 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?!
  25. 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
  26. 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
  27. 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
  28. 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
  29. -Shared element Transition -Transition Listener -Enter / Exit Transition -Property

    Animation System -Delayed Transitions -Circular Reveal
  30. 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