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

Transitions without Activities or Fragments

Chris Horner
November 05, 2017

Transitions without Activities or Fragments

Android's Transition framework is extremely powerful, but almost all examples involve the use of Activities and Fragments. In a world where many developers are now foregoing Fragments, this talk aims to provide some solid examples and strategies on how to use Transitions without them.

Chris Horner

November 05, 2017
Tweet

More Decks by Chris Horner

Other Decks in Technology

Transcript

  1. This is not a Fragment bashing talk • Conductor •

    Flow • Pancakes • PancakesOnPlates • Scoop • Cicerone • BackStack • Magellan • Simple Stack • Triad • Okuki • Navi
  2. <FrameLayout> <!-- Map and text… -->
 <LinearLayout> <TextView android:text=“Alarm”/> <TextView

    android:text=“Triggering…”/> <Space android:layout_weight=“1”/> <Button android:text=“Call 000”/> <Button android:text=“Help” android:layout_marginBottom=“280dp”/> </LinearLayout> </FrameLayout>
  3. <FrameLayout> <!-- Map and text… -->
 <LinearLayout android:background=“#F2F2F2”> <TextView android:text=“Alarm”/>

    <TextView android:text=“Triggering…”/> <Space android:layout_weight=“1”/> <Button android:text=“Call 000”/> <Button android:text=“Help” android:layout_marginBottom=“280dp”/> </LinearLayout> </FrameLayout>
  4. helpButton.setOnClickListener(v -> { TransitionManager.beginDelayedTransition(linearContainer); LayoutParams containerParams = linearContainer.getLayoutParams(); containerParams.height =

    LayoutParams.WRAP_CONTENT; title.setVisibility(View.GONE); instructions.setVisibility(View.GONE); helpButton.setVisibility(View.GONE); okButton.setVisibility(View.VISIBLE); });
  5. helpButton.setOnClickListener(v -> { TransitionManager.beginDelayedTransition(linearContainer); LayoutParams containerParams = linearContainer.getLayoutParams(); containerParams.height =

    LayoutParams.WRAP_CONTENT; title.setVisibility(View.GONE); instructions.setVisibility(View.GONE); helpButton.setVisibility(View.GONE); okButton.setVisibility(View.VISIBLE); });
  6. Transition transition = new TransitionSet() .addTransition(new Fade() .addTarget(title) .addTarget(instructions) .addTarget(helpButton)

    .addTarget(okButton)) .addTransition(new ChangeBounds() .addTarget(linearContainer)); TransitionManager .beginDelayedTransition(linearContainer, transition); Customise the Transition
  7. Transition transition = new TransitionSet() .addTransition(new Fade() .addTarget(title) .addTarget(instructions) .addTarget(helpButton)

    .addTarget(okButton)) .addTransition(new ChangeBounds() .addTarget(linearContainer)); TransitionManager .beginDelayedTransition(linearContainer, transition);
  8. Transition transition = new TransitionSet() .addTransition(new Fade() .addTarget(title) .addTarget(instructions) .addTarget(helpButton)

    .addTarget(okButton)) .addTransition(new ChangeBounds() .addTarget(linearContainer)); TransitionManager .beginDelayedTransition(linearContainer, transition);
  9. Transition transition = new TransitionSet() .addTransition(new Fade() .addTarget(title) .addTarget(instructions) .addTarget(helpButton)

    .addTarget(okButton)) .addTransition(new ChangeBounds() .addTarget(linearContainer)); TransitionManager .beginDelayedTransition(linearContainer, transition);
  10. Transition transition = new TransitionSet() .addTransition(new Fade() .addTarget(title) .addTarget(instructions) .addTarget(helpButton)

    .addTarget(okButton)) .addTransition(new ChangeBounds() .addTarget(linearContainer) .addTarget(callButton)); TransitionManager .beginDelayedTransition(linearContainer, transition);
  11. Transition transition = new TransitionSet() .addTransition(new Fade() .addTarget(title) .addTarget(instructions) .addTarget(helpButton)

    .addTarget(okButton)) .addTransition(new ChangeBounds() .addTarget(linearContainer) .addTarget(callButton) .addTarget(okButton) .addTarget(helpButton)); TransitionManager .beginDelayedTransition(linearContainer, transition);
  12. <FrameLayout> <!-- Map and text… —>
 <LinearLayout android:background=“#F2F2F2”> <TextView android:text=“Alarm”/>

    <TextView android:text=“Triggering…”/> <Space android:layout_weight=“1”/> <Button android:text=“Call 000”/> <Button android:text=“Help” android:layout_marginBottom=“280dp”/> </LinearLayout> </FrameLayout>
  13. <FrameLayout> <!-- Map and text… —> <View android:background=“#F2F2F2”/>
 <LinearLayout> <TextView

    android:text=“Alarm”/> <TextView android:text=“Triggering…”/> <Space android:layout_weight=“1”/> <Button android:text=“Call 000”/> <Button android:text=“Help” android:layout_marginBottom=“280dp”/> </LinearLayout> </FrameLayout>
  14. <!-- Map and text… —> <View android:background=“#F2F2F2”/>
 <LinearLayout> <TextView android:text=“Alarm”/>

    <TextView android:text=“Triggering…”/> </LinearLayout> <LinearLayout> <Button android:text=“Call 000”/> <Button android:text=“Help” android:layout_marginBottom=“280dp”/> </LinearLayout>
  15. <!-- Map and text… —> <View android:background=“#F2F2F2” android:layout_height=“???”/>
 <LinearLayout> <TextView

    android:text=“Alarm”/> <TextView android:text=“Triggering…”/> </LinearLayout> <LinearLayout android:layout_height=“wrap_content”> <Button android:text=“Call 000”/> <Button android:text=“Help” android:layout_marginBottom=“280dp”/> </LinearLayout>
  16. <ConstraintLayout> <!-- Map and text… —> <View android:background=“#F2F2F2”/>
 <TextView android:text=“Alarm”/>

    <TextView android:text=“Triggering…”/> <Button android:text=“Call 000”/> <Button android:text=“Help”/> </ConstraintLayout>
  17. <ConstraintLayout> <!-- Map and text… —> <View android:background=“#F2F2F2”/>
 <TextView android:text=“Alarm”/>

    <TextView android:text=“Triggering…”/> <Guideline app:layout_constraintGuide_percent=“0.6”/> <Button android:text=“Call 000”/> <Button android:text=“Help”/> </ConstraintLayout>
  18. ConstraintLayout container = findViewById(R.id.container); ConstraintSet idleSet = new ConstraintSet(); ConstraintSet

    triggeredSet = new ConstraintSet(); idleSet.clone(container); triggeredSet.clone(container); Take advantage of ConstraintSet
  19. ConstraintLayout container = findViewById(R.id.container); ConstraintSet idleSet = new ConstraintSet(); ConstraintSet

    triggeredSet = new ConstraintSet(); idleSet.clone(container); triggeredSet.clone(container); triggeredSet.setVisibility(R.id.title, View.GONE); triggeredSet.setVisibility(R.id.instructions, View.GONE); triggeredSet.setVisibility(R.id.helpButton, View.GONE); triggeredSet.setVisibility(R.id.okButton, View.VISIBLE); triggeredSet.connect(R.id.whiteBackground, ConstraintSet.TOP, R.id.guideline, ConstraintSet.TOP); Take advantage of ConstraintSet
  20. ConstraintLayout container = findViewById(R.id.container); ConstraintSet idleSet = new ConstraintSet(); ConstraintSet

    triggeredSet = new ConstraintSet(); idleSet.clone(container); triggeredSet.clone(container); triggeredSet.setVisibility(R.id.title, View.GONE); triggeredSet.setVisibility(R.id.instructions, View.GONE); triggeredSet.setVisibility(R.id.helpButton, View.GONE); triggeredSet.setVisibility(R.id.okButton, View.VISIBLE); triggeredSet.connect(R.id.whiteBackground, ConstraintSet.TOP, R.id.guideline, ConstraintSet.TOP); helpButton.setOnClickListener(v -> { TransitionManager.beginDelayedTransition(container); triggeredSet.applyTo(container); }); Take advantage of ConstraintSet
  21. public class AutoTransition extends TransitionSet { private void init() {

    setOrdering(ORDERING_SEQUENTIAL); addTransition(new Fade(Fade.OUT)); addTransition(new ChangeBounds()); addTransition(new Fade(Fade.IN)); } }
  22. Transition transition = new TransitionSet() .addTransition(new Fade() .addTarget(title) .addTarget(instructions) .setDuration(100))

    .addTransition(new Fade() .addTarget(helpButton) .addTarget(okButton) .setDuration(400)) .addTransition(new ChangeBounds() .setDuration(400) .setInterpolator(new FastOutSlowInInterpolator()); TransitionManager .beginDelayedTransition(container, transition);
  23. ViewGroup Transition transition = new TransitionSet() .addTransition(new Slide(Gravity.START) .addTarget(homeView) .setInterpolator(new

    FastOutSlowInInterpolator()) .addTransition(new Slide(Gravity.END) .addTarget(alarmView) .setInterpolator(new FastOutSlowInInterpolator()); TransitionManager .beginDelayedTransition(viewGroup, transition); viewGroup.remove(homeView); viewGroup.add(alarmView); A nicer Slide
  24. ViewGroup Transition transition = new TransitionSet() .addTransition(new Slide(Gravity.START) .addTarget(alarmView) .setInterpolator(new

    FastOutSlowInInterpolator()); TransitionManager .beginDelayedTransition(viewGroup, transition); viewGroup.remove(homeView); viewGroup.add(alarmView);
  25. ViewGroup Sliding over Transition transition = new TransitionSet() .addTransition(new Slide(Gravity.BOTTOM)

    .addTarget(alarmView) .setInterpolator(new LinearOutSlowInInterpolator()); TransitionManager .beginDelayedTransition(viewGroup, transition); viewGroup.remove(homeView); viewGroup.add(alarmView);
  26. ViewGroup Transition transition = new TransitionSet() .addTransition(new Fade() .addTarget(homeView) .setStartDelay(300)

    .setDuration(0)) .addTransition(new Slide(Gravity.BOTTOM) .addTarget(alarmView) .setInterpolator(new LinearOutSlowInInterpolator()); TransitionManager .beginDelayedTransition(viewGroup, transition); viewGroup.remove(homeView); viewGroup.add(alarmView); Sliding over
  27. ViewGroup Transition transition = new TransitionSet() .addTransition(new Fade() .addTarget(homeView) .setStartDelay(300)

    .setDuration(0)) .addTransition(new Slide(Gravity.BOTTOM) .addTarget(alarmView) .setInterpolator(new LinearOutSlowInInterpolator()); TransitionManager .beginDelayedTransition(viewGroup, transition); viewGroup.remove(homeView); viewGroup.add(alarmView); Sliding over
  28. ViewGroup Transition transition = new TransitionSet() .addTransition(new Slide(Gravity.BOTTOM) .addTarget(alarmView) .setInterpolator(new

    LinearOutSlowInInterpolator()); TransitionManager .beginDelayedTransition(viewGroup, transition); viewGroup.remove(homeView); viewGroup.add(alarmView);
  29. ViewGroup Transition transition = new TransitionSet() .addTransition(new Slide(Gravity.BOTTOM) .addTarget(alarmView) .setInterpolator(new

    LinearOutSlowInInterpolator()); TransitionManager .beginDelayedTransition(viewGroup, transition); viewGroup.remove(homeView); viewGroup.add(alarmView);
  30. ViewGroup Transition transition = new TransitionSet() .addTransition(new Slide(Gravity.BOTTOM) .addTarget(alarmView) .setInterpolator(new

    LinearOutSlowInInterpolator()); TransitionManager .beginDelayedTransition(viewGroup, transition); viewGroup.add(alarmView);
  31. ViewGroup Transition transition = new TransitionSet() .addTransition(new Slide(Gravity.BOTTOM) .addTarget(alarmView) .setInterpolator(new

    LinearOutSlowInInterpolator()) .addListener(new Transition.TransitionListener() { @Override onTransitionEnd(Transition transition) { container.removeView(homeView); } }); TransitionManager .beginDelayedTransition(viewGroup, transition); viewGroup.add(alarmView);
  32. ViewGroup Transition transition = new TransitionSet() .addTransition(new Slide(Gravity.BOTTOM) .addTarget(alarmView) .setInterpolator(new

    LinearOutSlowInInterpolator()) .addListener(new Transition.TransitionListener() { @Override onTransitionEnd(Transition transition) { container.removeView(homeView); } }); TransitionManager .beginDelayedTransition(viewGroup, transition); viewGroup.add(alarmView);
  33. ViewGroup Sharing elements Transition transition = new TransitionSet() .addTransition(new Slide(Gravity.BOTTOM)

    .addTarget(alarmView) .setInterpolator(new LinearOutSlowInInterpolator());
  34. ViewGroup Transition transition = new TransitionSet() .addTransition(new Slide(Gravity.BOTTOM) .addTarget(alarmView) .setInterpolator(new

    LinearOutSlowInInterpolator()) .addTransition(new ChangeBounds() .addTarget(homeView.fab) .addTarget(alarmView.fab)); Sharing elements
  35. ViewGroup Transition transition = new TransitionSet() .addTransition(new Slide(Gravity.BOTTOM) .addTarget(alarmView) .setInterpolator(new

    LinearOutSlowInInterpolator()) .addTransition(new ChangeBounds() .addTarget(homeView.fab) .addTarget(alarmView.fab)); TransitionManager .beginDelayedTransition(viewGroup, transition); viewGroup.add(alarmView); Sharing elements
  36. ViewGroup <FrameLayout android:layout_width=“match_parent” android:layout_height=“match_parent” > <ConstraintLayout android:id=“@+id/contentContainer” android:layout_width=“match_parent” android:layout_height=“match_parent” >

    <FloatingActionButton android:id=“@+id/fab” android:layout_width=“wrap_content” android:layout_height=“wrap_content” > </FrameLayout> Breaking up views
  37. ViewGroup Transition transition = new TransitionSet() .addTransition(new Slide(Gravity.BOTTOM) .addTarget(alarmView) .setInterpolator(new

    LinearOutSlowInInterpolator()) .addTransition(new ChangeBounds() .addTarget(homeView.fab) .addTarget(alarmView.fab)); TransitionManager .beginDelayedTransition(viewGroup, transition); viewGroup.add(alarmView);
  38. ViewGroup Transition transition = new TransitionSet() .addTransition(new Slide(Gravity.BOTTOM) .addTarget(alarmView.contentContainer) .setInterpolator(new

    LinearOutSlowInInterpolator()) .addTransition(new ChangeBounds() .addTarget(homeView.fab) .addTarget(alarmView.fab)); TransitionManager .beginDelayedTransition(viewGroup, transition); viewGroup.add(alarmView);
  39. ViewGroup Transition transition = new TransitionSet() .addTransition(new Slide(Gravity.BOTTOM) .addTarget(alarmView.contentContainer) .setInterpolator(new

    LinearOutSlowInInterpolator()) .addTransition(new ChangeBounds() .addTarget(homeView.fab) .addTarget(alarmView.fab)); TransitionManager .beginDelayedTransition(viewGroup, transition); viewGroup.add(alarmView);
  40. ViewGroup Transition transition = new TransitionSet() .addTransition(new Slide(Gravity.BOTTOM) .addTarget(alarmView.contentContainer) .setInterpolator(new

    LinearOutSlowInInterpolator()) .addTransition(new ChangeBounds() .addTarget(homeView.fab) .addTarget(alarmView.fab)); TransitionManager .beginDelayedTransition(viewGroup, transition); viewGroup.add(alarmView);
  41. ViewGroup Transition transition = new TransitionSet() .addTransition(new Slide(Gravity.BOTTOM) .addTarget(alarmView.contentContainer) .setInterpolator(new

    LinearOutSlowInInterpolator()) .addTransition(new ChangeBounds() .addTarget(homeView.fab) .addTarget(alarmView.fab)); TransitionManager .beginDelayedTransition(viewGroup, transition); viewGroup.add(alarmView); homeView.removeView(homeView.fab);
  42. ViewGroup <!-- home.xml --> <FloatingActionButton android:id=“@+id/fab” android:layout_width=“wrap_content” android:layout_height=“wrap_content” > 


    <!-- alarm.xml --> <FloatingActionButton android:id=“@+id/fab” android:layout_width=“wrap_content” android:layout_height=“wrap_content” >
  43. ViewGroup <!-- home.xml --> <FloatingActionButton android:id=“@+id/fab” android:layout_width=“wrap_content” android:layout_height=“wrap_content” > 


    <!-- alarm.xml --> <FloatingActionButton android:id=“@+id/fab” android:layout_width=“wrap_content” android:layout_height=“wrap_content” >
  44. ViewGroup <!-- home.xml --> <FloatingActionButton android:id=“@+id/home_fab” android:transitionName=“fab” android:layout_width=“wrap_content” android:layout_height=“wrap_content” >

    
 <!-- alarm.xml --> <FloatingActionButton android:id=“@+id/alarm_fab” android:transitionName=“fab” android:layout_width=“wrap_content” android:layout_height=“wrap_content” >
  45. Transition transition = new TransitionSet() .addTransition(new Fade() .addTarget(searchView.scrim)) .addTransition(new ChangeBounds()

    .addTarget(homeView.card) .addTarget(searchView.card)); <!-- home.xml -->
 
 <CardView android:transitionName=“card” />
 
 <!-- search.xml -->
 
 <CardView android:transitionName=“card” />
  46. Transition transition = new TransitionSet() .addTransition(new Fade() .addTarget(searchView.scrim)) .addTransition(new ChangeBounds()

    .addTarget(homeView.card) .addTarget(searchView.card)); TransitionManager .beginDelayedTransition(viewGroup, transition); container.addView(searchView); 
 <CardView android:transitionName=“card” />
 
 <!-- search.xml -->
 
 <CardView android:transitionName=“card” />
  47. Transition transition = new TransitionSet() .addTransition(new Fade() .addTarget(searchView.scrim)) .addTransition(new ChangeBounds()

    .addTarget(homeView.card) .addTarget(searchView.card)); TransitionManager .beginDelayedTransition(viewGroup, transition); container.addView(searchView);
  48. Transition transition = new TransitionSet() .addTransition(new Fade() .addTarget(searchView.scrim)) .addTransition(new ChangeBounds()

    .addTarget(homeView.card) .addTarget(searchView.card)); TransitionManager .beginDelayedTransition(viewGroup, transition); container.addView(searchView); homeView.removeView(homeView.card);
  49. Transition transition = new TransitionSet() .addTransition(new Fade() .addTarget(searchView.scrim)) .addTransition(new ChangeBounds()

    .addTarget(homeView.card) .addTarget(searchView.card)); TransitionManager .beginDelayedTransition(viewGroup, transition); homeView.removeView(homeView.card);
  50. Transition transition = new TransitionSet() .addTransition(new Fade() .addTarget(searchView.scrim)) .addTransition(new ChangeBounds()

    .addTarget(homeView.card) .addTarget(searchView.card)); TransitionManager .beginDelayedTransition(viewGroup, transition); homeView.removeView(homeView.card);
  51. Transition transition = new TransitionSet() .addTransition(new Fade() .addTarget(searchView.scrim)) .addTransition(new TransitionSet()

    .addTransition(new ChangeBounds()) .addTransition(new ChangeTransform()) .addTarget(homeView.card) .addTarget(searchView.card)); TransitionManager .beginDelayedTransition(viewGroup, transition); homeView.removeView(homeView.card);
  52. Transition transition = new TransitionSet() .addTransition(new Fade() .addTarget(searchView.scrim)) .addTransition(new TransitionSet()

    .addTransition(new ChangeBounds()) .addTransition(new ChangeTransform()) .addTarget(homeView.card) .addTarget(searchView.card)); TransitionManager .beginDelayedTransition(viewGroup, transition); homeView.addView(homeView.card); container.removeView(searchView); What about going back?
  53. Transition transition = new TransitionSet() .addTransition(new Fade() .addTarget(searchView.scrim)) .addTransition(new TransitionSet()

    .addTransition(new ChangeBounds()) .addTransition(new ChangeTransform()) .addTarget(homeView.card) .addTarget(searchView.card)); TransitionManager .beginDelayedTransition(viewGroup, transition); homeView.addView(homeView.card); container.removeView(searchView);
  54. Transition transition = new TransitionSet() .addTransition(new Fade() .addTarget(searchView.scrim)) .addTransition(new TransitionSet()

    .addTransition(new ChangeBounds()) .addTransition(new ChangeTransform()) .addTarget(homeView.card) .addTarget(searchView.card)); TransitionManager .beginDelayedTransition(viewGroup, transition); homeView.addView(homeView.card); container.removeView(searchView);
  55. Transition transition = new TransitionSet() .addTransition(new Fade() .addTarget(searchView.scrim)) .addTransition(new TransitionSet()

    .addTransition(new ChangeBounds()) .addTransition(new ChangeTransform()) .addTarget(R.id.homeCard) .addTarget(searchView.card)); TransitionManager .beginDelayedTransition(viewGroup, transition); homeView.addView(homeView.card); container.removeView(searchView);
  56. Debugging tips • Know your layout hierarchy • ChangeBounds() is

    a good place to start investigating • Try starting with simplified versions of your screens
  57. Things to remember • Transitions are powerful; don’t ignore them

    • Choose your view-based navigation library carefully • Use them to enhance UX, not show off