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

Building Beautiful Apps with the Design Support Library

1cf799036b5d9439e9ed823c9b0c15cb?s=47 Joe Birch
August 02, 2016

Building Beautiful Apps with the Design Support Library

Since Material Design has been introduced to the world of Android, many applications are still not making the most out of what's provided to us out-of-the-box to help us create material styled apps. In this class, we'll take a look at the capabilities of the design support library and how we can implement the numerous components that it provides to help us create beautiful and polished material influenced applications. As well as taking a deep dive into these components and their various attributes, we'll also take a look at how you can add subtle animations to compliment your material apps even further!

1cf799036b5d9439e9ed823c9b0c15cb?s=128

Joe Birch

August 02, 2016
Tweet

Transcript

  1. Building Beautiful Apps with the Android Support Libraries

  2. Joe Birch Android Engineer @Buffer @hitherejoe / hitherejoe.com

  3. Android Support Libraries

  4. Support Libraries Design Support Custom Tabs Recycler View + more

    Animations
  5. Recycler View

  6. None
  7. <android.support.v7.widget.RecyclerView android:id=“+id/recycler_view“ android:layout_width=“match_parent" android:layout_height="wrap_content"/>

  8. Layout Manager - How to layout views Item Animator -

    How to animate views Adapter - Provides views
  9. mRecycler.setLayoutManager(new LinearLayoutManager(this)); mRecycler.setAdapter(mRecyclerAdapter);

  10. public class YourAdapter extends RecyclerView.Adapter<YourAdapter.YourViewHolder> { @Override public YourViewHolder onCreateViewHolder(ViewGroup

    parent, int viewType) { } @Override public void onBindViewHolder(YourViewHolder holder, int position) { } class YourViewHolder extends RecyclerView.ViewHolder { public YourViewHolder(View itemView) { } } }
  11. public class YourAdapter extends RecyclerView.Adapter<YourAdapter.YourViewHolder> { @Override public YourViewHolder onCreateViewHolder(ViewGroup

    parent, int viewType) { // inflate layout return new YourViewHolder(view); } @Override public void onBindViewHolder(YourViewHolder holder, int position) { // set view data } class YourViewHolder extends RecyclerView.ViewHolder { public YourViewHolder(View itemView) { super(itemView); // construct view holder } } }
  12. public class YourAdapter extends RecyclerView.Adapter<YourAdapter.YourViewHolder> { @Override public YourViewHolder onCreateViewHolder(ViewGroup

    parent, int viewType) { // inflate layout return new YourViewHolder(view); } @Override public void onBindViewHolder(YourViewHolder holder, int position) { // set view data } class YourViewHolder extends RecyclerView.ViewHolder { public YourViewHolder(View itemView) { super(itemView); // construct view holder } } }
  13. public class YourAdapter extends RecyclerView.Adapter<YourAdapter.YourViewHolder> { @Override public YourViewHolder onCreateViewHolder(ViewGroup

    parent, int viewType) { // inflate layout return new YourViewHolder(view); } @Override public void onBindViewHolder(YourViewHolder holder, int position) { // set view data } class YourViewHolder extends RecyclerView.ViewHolder { public YourViewHolder(View itemView) { super(itemView); // construct view holder } } }
  14. - More powerful and flexible than list view - Decouples

    list from container, easily add items at runtime
  15. - More powerful and flexible than list view - Follows

    best-practices using ViewHolder - Enforced, ListView was optional - Decouples list from container, easily add items at runtime
  16. - More powerful and flexible than list view - Follows

    best-practices using ViewHolder - Enforced, ListView was optional - No dividers by default = more material - Decouples list from container, easily add items at runtime
  17. - More powerful and flexible than list view - Follows

    best-practices using ViewHolder - Enforced, ListView was optional - No dividers by default = more material - Use LayoutManager for different lists or grids - Decouples list from container, easily add items at runtime
  18. LinearLayoutManager lm = new LinearLayoutManager(this); GridLayoutManager lm = new GridLayoutManager(this,

    4); StaggeredGridLayoutManager lm = new StaggeredGridLayoutManager(3, VERTICAL); mRecyclerView.setLayoutManager(lm);
  19. - More powerful and flexible than list view - Follows

    best-practices using ViewHolder - Enforced, ListView was optional - No dividers by default = more material - Use LayoutManager for different lists or grids - Simpler animations using ItemAnimator - Decouples animations, hands over to ItemAnimator - Decouples list from container, easily add items at runtime
  20. Swipe Refresh layout

  21. None
  22. <android.support.v4.widget.SwipeRefreshLayout android:id=“+id/swipe_to_refresh“ android:layout_width=“match_parent" android:layout_height=“match_parent”> // child view(s) goes here </android.support.v4.widget.SwipeRefreshLayout>

  23. mSwipeRefreshLayout.setOnRefreshListener( new SwipeRefreshLayout.OnRefreshListener() { @Override public void onRefresh() { //

    do stuff! } });
  24. - Allow the user to easily refresh content - Whilst

    also showing them it’s taking place
  25. - Allow the user to easily refresh content - Customise

    the colour of the PTR circle - Whilst also showing them it’s taking place
  26. mSwipeRefreshLayout.setProgressBackgroundColorSchemeResource(R.color.primary); mSwipeRefreshLayout.setColorSchemeResources(R.color.white);

  27. - Allow the user to easily refresh content - Customise

    the colour of the PTR circle - Manually use setRefreshing() - Manually display PTR circle, this could be when updating from a service etc - Whilst also showing them it’s taking place
  28. Floating Action Button

  29. None
  30. Normal - 56dp Mini - 40dp

  31. <android.support.design.widget.FloatingActionButton android:layout_width="wrap_content" android:layout_height=“wrap_content” android:src=“@drawable/ic_heart“ app:fabSize="normal" />

  32. None
  33. mFloatingActionButton.setOnClickListener(new View.OnClickListener() {
 @Override
 public void onClick(View view) {
 Snackbar.make(view,

    "Hey! I'm a Snackbar”, Snackbar.LENGTH_LONG).show();
 }
 });
  34. - One per screen, dominant action - Even on tabbed

    content
  35. - One per screen, dominant action - Avoid minor or

    destructive actions - Even on tabbed content
  36. Do:

  37. Do: Don’t:

  38. - One per screen, dominant action - Avoid minor or

    destructive actions - Even on tabbed content - Not a replacement for an overflow menu
  39. - One per screen, dominant action - Avoid minor or

    destructive actions - Even on tabbed content - Not a replacement for an overflow menu - Get creative with animations and transitions
  40. None
  41. int centerX = (startView.getLeft() + startView.getRight()) / 2; int centerY

    = (startView.getTop() + startView.getBottom()) / 2; float finalRadius = (float) Math.hypot((double) centerX, (double) centerY); Animator mCircularReveal = ViewAnimationUtils.createCircularReveal( targetView, centerX, centerY, 0, finalRadius);
  42. None
  43. https://github.com/hitherejoe/animate

  44. Snackbar

  45. None
  46. Snackbar.make(mDrawerLayout, "Your message”, Snackbar.LENGTH_SHORT) .setAction(getString(R.string.text_undo), this) .show();

  47. None
  48. final Snackbar snackbar = Snackbar.make(mShotRecycler, "Hey, I'm a Snackbar", Snackbar.LENGTH_INDEFINITE);

    
 snackbar.setAction("UNDO", new View.OnClickListener() {
 @Override
 public void onClick(View v) {
 // Handle action click event
 }
 }); snackbar.setActionTextColor(color); snackbar.show();
  49. LENGTH_INDEFINITE LENGTH_LONG LENGTH_SHORT

  50. - Short informative messages

  51. - Short informative messages - Can replace toast notifications in

    most places
  52. - Short informative messages - Avoid adding iconography - Can

    replace toast notifications in most places
  53. - Short informative messages - Avoid adding iconography - Can

    replace toast notifications in most places - Only display a single action
  54. - Short informative messages - Avoid adding iconography - Can

    replace toast notifications in most places - Only display a single action - Don’t obstruct any displayed FAB
  55. DrawerLayout

  56. None
  57. <android.support.v4.widget.DrawerLayout android:id=“+id/drawer_main“ android:layout_width=“match_parent” android:layout_height=“match_parent” android:layout_gravity=“start”> // Views go here </android.support.v4.widget.DrawerLayout>

  58. - Display underneath status bar - Set transparent status bar

    in theme
  59. <item name="android:windowDrawsSystemBarBackgrounds">true</item>
 <item name="android:statusBarColor">@android:color/transparent</item>

  60. - Display underneath status bar - Use to display navigation

    for app ‘sections’ - Set transparent status bar in theme
  61. - Display underneath status bar - Use to display navigation

    for app ‘sections’ - Set transparent status bar in theme - Remember, pressing back should exit the app! - Common mistake to traverse back through fragments
  62. NavigationView

  63. None
  64. <android.support.v4.widget.DrawerLayout> <FrameLayout /> <android.support.design.widget.NavigationView android:id="@+id/navigation_view" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="start" app:headerLayout="@layout/navigation_header" app:menu="@menu/drawer"

    /> </android.support.v4.widget.DrawerLayout>
  65. - Should at least display navigation in the drawer! -

    Header section is optional
  66. NavigationView - HeaderLayout

  67. None
  68. <android.support.v4.widget.DrawerLayout> <FrameLayout /> <android.support.design.widget.NavigationView android:id="@+id/navigation_view" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="start" app:headerLayout="@layout/navigation_header" app:menu="@menu/drawer"

    /> </android.support.v4.widget.DrawerLayout>
  69. None
  70. <android.support.v4.widget.DrawerLayout> <FrameLayout /> <android.support.design.widget.NavigationView android:id="@+id/navigation_view" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="start" app:menu="@menu/drawer" />

    </android.support.v4.widget.DrawerLayout>
  71. - Generally used for user profile

  72. - Generally used for user profile - Great place for

    account switching
  73. - Generally used for user profile - Avoid large amounts

    of text - Great place for account switching - User photo, name, email, account info etc.
  74. - Generally used for user profile - Avoid large amounts

    of text - Great place for account switching - User photo, name, email, account info etc. - Declare layout using app:headerLayout
  75. NavigationView - Menu

  76. None
  77. <android.support.v4.widget.DrawerLayout> <FrameLayout /> <android.support.design.widget.NavigationView android:id="@+id/navigation_view" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_gravity="start" app:menu="@menu/drawer" />

    </android.support.v4.widget.DrawerLayout>
  78. <menu xmlns:android=“http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" tools:context=“.MainActivity”> <group android:checkableBehavior="single"> <item android:id="@+id/navigation_item_1" android:checked="true" android:icon="@drawable/ic_android"

    android:title="@string/navigation_item_1" /> <item android:id="@+id/navigation_item_2" android:icon="@drawable/ic_android" android:title="@string/navigation_item_2" /> </group> </menu>
  79. <menu xmlns:android=“http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" tools:context=“.MainActivity”> <group android:checkableBehavior="single"> <item android:id=“@+id/navigation_item_1" android:icon="@drawable/ic_android" android:title="@string/navigation_item_1"

    /> <item android:id="@+id/navigation_item_2" android:icon="@drawable/ic_android" android:title="@string/navigation_item_2" /> </group> </menu>
  80. <menu xmlns:android=“http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" tools:context=“.MainActivity”> <group android:checkableBehavior="single"> <item android:id="@+id/navigation_item_1" android:icon="@drawable/ic_android" android:title="@string/navigation_item_1"

    /> <item android:id="@+id/navigation_item_2" android:icon="@drawable/ic_android" android:title="@string/navigation_item_2" /> </group> </menu>
  81. <menu xmlns:android=“http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" tools:context=“.MainActivity”> <group android:checkableBehavior="single"> <item android:id="@+id/navigation_item_1" android:icon="@drawable/ic_android" android:title="@string/navigation_item_1"

    /> <item android:id="@+id/navigation_item_2" android:icon="@drawable/ic_android" android:title="@string/navigation_item_2" /> </group> </menu>
  82. None
  83. <menu xmlns:android=“http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" tools:context=“.MainActivity”> <group android:checkableBehavior="single"> <item android:id="@+id/navigation_subheader" android:title="@string/nav_header"> <menu>

    <!-- Menu items go here --> </menu> </item> </group> </menu>
  84. <menu xmlns:android=“http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" tools:context=“.MainActivity”> <group android:checkableBehavior="single"> <item android:id="@+id/navigation_subheader" android:title="@string/nav_header"> <menu>

    <!-- Menu items go here --> </menu> </item> </group> </menu>
  85. - Use iconography :)

  86. - Use iconography :) - e.g Dominant screens and ‘Generic’

    sections - Group related menu items
  87. - Use iconography :) - e.g Dominant screens and Generic

    sections - Group related menu items - Declare menu using app:menu
  88. EditText Floating Labels

  89. None
  90. <android.support.design.widget.TextInputLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <EditText android:id="@+id/edit_text_email" android:layout_width="match_parent" android:layout_height="wrap_content" android:inputType="textEmailAddress" android:hint="@string/hint_email" />

    </android.support.design.widget.TextInputLayout>
  91. <android.support.design.widget.TextInputLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <EditText android:id="@+id/edit_text_email" android:layout_width="match_parent" android:layout_height="wrap_content" android:inputType="textEmailAddress" android:hint="@string/hint_email" />

    </android.support.design.widget.TextInputLayout>
  92. <android.support.design.widget.TextInputLayout android:layout_width="match_parent" android:layout_height="wrap_content"> <EditText android:id="@+id/edit_text_email" android:layout_width="match_parent" android:layout_height="wrap_content" android:inputType="textEmailAddress" android:hint="@string/hint_email" />

    </android.support.design.widget.TextInputLayout>
  93. enable error at time of error enable error during initialisation

  94. setErrorEnabled(true); setError(getString(R.string.text_error_message));

  95. - Less disruptive than toasts, snackers and dialogs

  96. - Enable error during screen creation - Less disruptive than

    toasts, snackers and dialogs - Enable error during screen creation
  97. - Enable error during screen creation - Keep error to

    a single line - Less disruptive than toasts, snackers and dialogs
  98. - Enable error during screen creation - Clear the error

    programatically - Keep error to a single line - Less disruptive than toasts, snackers and dialogs
  99. TabLayout

  100. tabGravity=“fill” tabGravity=“center”

  101. None
  102. tabMode=“fixed” tabMode=“scrollable”

  103. <android.support.design.widget.TabLayout android:id="@+id/sliding_tabs" android:layout_width="match_parent" android:layout_height="wrap_content" app:tabMode="fixed" app:tabGravity="fill" />

  104. <android.support.design.widget.TabLayout android:id="@+id/sliding_tabs" android:layout_width="match_parent" android:layout_height="wrap_content" app:tabMode="fixed" app:tabGravity="fill" />

  105. <android.support.design.widget.TabLayout android:id="@+id/sliding_tabs" android:layout_width="match_parent" android:layout_height="wrap_content" app:tabMode="fixed" app:tabGravity="fill" />

  106. ViewPager pager = (ViewPager) rootView.findViewById(R.id.viewPager); pager.setAdapter(new MyPagerAdapter(getActivity().getSupportFragmentManager())); ————————————————— or———————————————————— TabLayout

    tabLayout = (TabLayout) rootView.findViewById(R.id.sliding_tabs); tabLayout.addTab(tabLayout.newTab().setText("Tab One")); tabLayout.addTab(tabLayout.newTab().setText("Tab Two")); tabLayout.addTab(tabLayout.newTab().setText("Tab Three")); tabLayout.setupWithViewPager(pager);
  107. - Single row above the displayed content

  108. - Single row above the displayed content - Keep titles

    short
  109. - Single row above the displayed content - Don’t nest

    swipes! - Keep titles short - Don’t nest swipes!
  110. - Single row above the displayed content - Don’t nest

    swipes! - Keep titles short - Used to switch between relatable categories
  111. - Single row above the displayed content - Don’t nest

    swipes! - Keep titles short - Used to switch between relatable categories - Collapse the toolbar when scrolling with tabs
  112. Coordinator Layout

  113. enterAlways exitUntilCollapsed

  114. <android.support.design.widget.CoordinatorLayout
 android:layout_width="match_parent"
 android:layout_height=“match_parent”> <android.support.v7.widget.RecyclerView app:layout_behavior="@string/appbar_scrolling_view_behavior" // other attributes /> </android.support.design.widget.AppBarLayout>

  115. <android.support.design.widget.CoordinatorLayout
 android:layout_width="match_parent"
 android:layout_height=“match_parent”> <android.support.v7.widget.RecyclerView app:layout_behavior="@string/appbar_scrolling_view_behavior" // other attributes /> </android.support.design.widget.AppBarLayout>

  116. - CoordinatorLayout helps save screen estate - More space for

    content!
  117. - CoordinatorLayout helps save screen estate - More space for

    content! - Collapse the toolbar when scrolling with tabs
  118. - CoordinatorLayout helps save screen estate - Simple to add!

    - More space for content! - Collapse the toolbar when scrolling with tabs
  119. - CoordinatorLayout helps save screen estate - Simple to add!

    - More space for content! - Use the app:layout_behavior=“@string/ appbar_scrolling_view_behavior" flag - Collapse the toolbar when scrolling with tabs
  120. Collapsing Toolbar Layout

  121. pin parallax

  122. <android.support.design.widget.CollapsingToolbarLayout android:layout_width="match_parent"
 android:layout_height=“match_parent” app:layout_scrollFlags="scroll|enterAlways" > <android.support.v7.widget.Toolbar
 android:id="@+id/toolbar_main"
 android:layout_width="match_parent"
 android:layout_height="?attr/actionBarSize"
 app:layout_collapseMode=“pin"


    app:theme="@style/AppTheme.ToolbarStyle" /> </android.support.design.widget.AppBarLayout>
  123. <android.support.design.widget.CollapsingToolbarLayout android:layout_width="match_parent"
 android:layout_height=“match_parent” app:layout_scrollFlags="scroll|enterAlways" > <android.support.v7.widget.Toolbar
 android:id="@+id/toolbar_main"
 android:layout_width="match_parent"
 android:layout_height="?attr/actionBarSize"
 app:layout_collapseMode=“pin"


    app:theme="@style/AppTheme.ToolbarStyle" /> </android.support.design.widget.AppBarLayout>
  124. - Use Parallax to fade out images - Use Parallax

    multiplier attribute
  125. - Use Parallax to fade out images - or if

    you don’t want to fade out images! - Use Pin for solid colours - Use Parallax multiplier attribute
  126. Toolbar

  127. None
  128. <android.support.v7.widget.Toolbar
 android:id="@+id/toolbar_main"
 android:layout_width="match_parent"
 android:layout_height="?attr/actionBarSize"
 app:layout_scrollFlags="scroll|enterAlways"
 app:theme="@style/AppTheme.ToolbarStyle" />

  129. <android.support.v7.widget.Toolbar
 android:id="@+id/toolbar_main"
 android:layout_width="match_parent"
 android:layout_height="?attr/actionBarSize"
 app:layout_scrollFlags="scroll|enterAlways"
 app:theme="@style/AppTheme.ToolbarStyle" />

  130. - More flexible than ActionBar - It’s a part of

    our view hierarchy!
  131. - More flexible than ActionBar - It’s a part of

    our view hierarchy! - Dominant, above all app content - All content scrolls underneath! - Dominant, above all app content - All content scrolls underneath!
  132. - More flexible than ActionBar - It’s a part of

    our view hierarchy! - Dominant, above all app content - All content scrolls underneath! - Use with Coordinator layout to collapse
  133. - More flexible than ActionBar - It’s a part of

    our view hierarchy! - Dominant, above all app content - All content scrolls underneath! - Use with Coordinator layout to collapse - Set using setSupportActionBar(toolbar); - Disable action bar in theme
  134. Bottom Sheets

  135. Modal Persistent

  136. - Modal for menus, Persistent for content

  137. - Modal for menus, Persistent for content - Display after

    user-initiated action
  138. - Modal for menus, Persistent for content - Only size

    them using the space they need - Display after user-initiated action
  139. - Modal for menus, Persistent for content - Only size

    them using the space they need - Display after user-initiated action - Declare view with bottom sheet behaviour - app:layout_behavior=“@string/bottom_sheet_behavior"
  140. DayNight Theme

  141. day night

  142. - Extend from the theme

  143. <style name=“MyTheme” parent="Theme.AppCompat.DayNight"> </style>

  144. - Extend from the theme - Enable the feature in

    Application class
  145. AppCompatDelegate.setDefaultNightMode( AppCompatDelegate.MODE_NIGHT_...);

  146. - Extend from the theme - Update in component as

    required - Enable the feature in Application class
  147. getDelegate().setLocalNightMode( AppCompatDelegate.MODE_NIGHT_...); // Now recreate for it to take effect

    recreate();
  148. - Extend from the theme - Update in component as

    required - Enable the feature in Application class - Check mode and act accordingly!
  149. int currentNightMode = getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK; switch (currentNightMode) { case

    Configuration.UI_MODE_NIGHT_NO: // Night mode is not active, we're in day time case Configuration.UI_MODE_NIGHT_YES: // Night mode is active, we're at night! case Configuration.UI_MODE_NIGHT_UNDEFINED: // We don't know what mode we're in, assume not night }
  150. Palette

  151. // Synchronous Palette p = Palette.from(mBitmap).generate(); // Asynchronous Palette.from(mBitmap).generate(new PaletteAsyncListener()

    { public void onGenerated(Palette p) { // Use generated instance } });
  152. int vibrant = palette.getVibrantColor(default); int vibrantLight = palette.getLightVibrantColor(default); int vibrantDark

    = palette.getDarkVibrantColor(default); int muted = palette.getMutedColor(default); int mutedLight = palette.getLightMutedColor(default); int mutedDark = palette.getDarkMutedColor(default);
  153. Constraint Layout

  154. None
  155. app:layout_constraintBottom_toBottomOf=”@+id/constraintLayout” app:layout_constraintEnd_toEndOf=”@+id/constraintLayout” app:layout_constraintStart_toStartOf=”@+id/constraintLayout” app:layout_constraintTop_toTopOf=”@+id/constraintLayout” app:layout_constraintEnd_toStartOf=”@+id/imageView”

  156. - Currently in alpha

  157. - Currently in alpha - Relative-Layout on steroids! - Reduce

    nested containers - Simplify view layout relationships
  158. Custom Tabs

  159. None
  160. int color = ContextCompat.getColor(context, R.color.primary); Bitmap icon = BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_arrow_back);

    CustomTabsIntent customTabsIntent = new CustomTabsIntent.Builder() .setToolbarColor(color) .setShowTitle(true) .setCloseButtonIcon(icon) .addDefaultShareMenuItem() .build(); Intent intent = customTabsIntent.intent; intent.setData(uri); startActivity(intent);
  161. - Help provide a seamless experience

  162. - Help provide a seamless experience - Built-in share functionality

  163. - Help provide a seamless experience - Built-in share functionality

    - Theme browser bar to application color
  164. - Help provide a seamless experience - Built-in share functionality

    - Theme browser bar to application color - Performance enhancements
  165. Touch States

  166. ?android:attr/selectableItemBackground

  167. ?android:attr/selectableItemBackgroundBorderless

  168. View Property Animator

  169. alpha() scaleX() & scaleY() translationZ() setDuration() setStartDelay() setInterpolator() setListener()

  170. Interpolators

  171. Fast-Out-Linear-In Accelerate-Decelerate Linear-Out-Slow-In

  172. Object Animator

  173. None
  174. private void animateForegroundColor(@ColorInt final int targetColor) { ObjectAnimator animator =

    ObjectAnimator.ofInt(YOUR_VIEW, FOREGROUND_COLOR, Color.TRANSPARENT, targetColor); animator.setEvaluator(new ArgbEvaluator()); animator.setStartDelay(DELAY_COLOR_CHANGE); animator.start(); }
  175. private void resizeView() { final float widthHeightRatio = (float) getHeight()

    / (float) getWidth(); resizeViewProperty(View.SCALE_X, .5f, 200); resizeViewProperty(View.SCALE_Y, .5f / widthHeightRatio, 250); } private void resizeViewProperty(Property<View, Float> property, float targetScale, int durationOffset) { ObjectAnimator animator = ObjectAnimator.ofFloat(this, property, 1f, targetScale); animator.setInterpolator(new LinearOutSlowInInterpolator()); animator.setStartDelay(DELAY_COLOR_CHANGE + durationOffset); animator.start(); }
  176. Window Transitions

  177. enter - Determines how an activity’s views enter the scene

    exit - Determines how an activity’s views exit the scene reenter - Determines how an activity reenters after previously exiting shared elements - Determines how shared views transition between activities
  178. enter - Determines how an activity’s views enter the scene

    exit - Determines how an activity’s views exit the scene reenter - Determines how an activity reenters after previously exiting shared elements - Determines how shared views transition between activities
  179. enter - Determines how an activity’s views enter the scene

    exit - Determines how an activity’s views exit the scene reenter - Determines how an activity reenters after previously exiting shared elements - Determines how shared views transition between activities
  180. enter - Determines how an activity’s views enter the scene

    exit - Determines how an activity’s views exit the scene reenter - Determines how an activity reenters after previously exiting shared elements - Determines how shared views transition between activities
  181. Explode Transition

  182. None
  183. <android.support.v7.widget.Toolbar
 android:id="@+id/toolbar_main"
 android:layout_width="match_parent"
 android:layout_height="?attr/actionBarSize"
 app:layout_scrollFlags="scroll|enterAlways"
 app:theme="@style/AppTheme.ToolbarStyle" />

  184. <explode xmlns:android="http://schemas.android.com/apk/res/android" android:duration="300"/>

  185. <style name="AppTheme.Explode" parent="AppTheme.NoActionBar"> <item name="android:windowExitTransition">@transition/explode</item> <item name="android:windowReenterTransition">@android:transition/slide_top</item> </style>

  186. Slide Transition

  187. None
  188. <slide xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:interpolator/decelerate_cubic" android:slideEdge="end"/>

  189. <style name="AppTheme.Slide" parent="AppTheme.NoActionBar"> <item name="android:windowExitTransition">@transition/slide</item> <item name="android:windowReenterTransition">@android:transition/slide_top</item> </style>

  190. Fade Transition

  191. None
  192. <fade xmlns:android="http://schemas.android.com/apk/res/android" android:duration="300"/>

  193. <style name="AppTheme.Fade" parent="AppTheme.NoActionBar"> <item name="android:windowExitTransition">@transition/fade</item> <item name="android:windowReenterTransition">@android:transition/slide_top</item> </style>

  194. Excluding Views

  195. <fade xmlns:android="http://schemas.android.com/apk/res/android" android:duration=“300"> <targets> <target android:excludeId="@android:id/navigationBarBackground"/> <target android:excludeId="@android:id/statusBarBackground"/> </targets> </fade>

  196. Shared Element Transitions

  197. None
  198. <View android:id=“@+id/view_shared_transition_one" android:transitionName=“@string/transition_view"/> <View android:id=“@+id/view_shared_transition_two" android:transitionName="@string/transition_view"/> Screen One Screen Two

  199. Pair participants = new Pair<>(mSquareView, ViewCompat.getTransitionName(mSquareView)); ActivityOptionsCompat transitionActivityOptions = ActivityOptionsCompat.makeSceneTransitionAnimation(

    SharedTransitionsActivity.this, participants); ActivityCompat.startActivity(SharedTransitionsActivity.this, intent, transitionActivityOptions.toBundle());
  200. Keep up-to-date

  201. Resources

  202. Resources Official Android Documentation G+ Android Developer Community github.com/hitherejoe medium.com/@hitherejoe

    G+ Android Design Community Official Google Design Documentation