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

Material all the things!

Material all the things!

Building beautiful, usable products with Material Design might be quite long especially if your app supports old Android versions. Thanks to the Material components library, Google has finally given us the keys to fully and easily implement their design concepts.

Through this talk, we will take a deep dive into this library to see what it brings on the table (theming, motion, transition, shapes, typography…) and how to implement Material components with some live action samples.

56047a7b11797f42c2e7030d771fe803?s=128

Julien Salvi

October 17, 2020
Tweet

Transcript

  1. Material All the Things! Renaud Mathieu & Julien Salvi Innovorder

  2. Material back in the days!

  3. Material Design history 2014 2016 2018 2020 2022 Design Material

    Design introduction Material Design 2 Material lib 1.3.0-alpha03 Material lib 1.0.0 Tools Material lib 1.0.0-alpha01 Suppo Design library Compose Material lib
  4. • Google provided a lot of resources for designer •

    But libraries and tools for developers were missing • Build your own components DIY! Material Design resources back then…
  5. • Implementing a Material Button back in the days! •

    Spoiler alert: lots of code! Material Button back then! BUTTON BUTTON
  6. Material Button back then! BUTTON BUTTON <Button android:id="@+id/trailer" android:layout_width="wrap_content" android:layout_height="36dp"

    android:background="@drawable/btn_trailer" android:paddingStart="32dp" android:paddingEnd="32dp" android:text="@string/trailer" android:letterSpacing="0.05" android:textColor="@color/white" android:textSize="12sp" android:textStyle="bold"/>
  7. Add a shape and background BUTTON BUTTON <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item

    android:state_pressed="true"> <shape> <solid android:color="@color/btn_color_pressed" /> <corners android:radius="4dp" /> </shape> </item> <item> <shape> <solid android:color="@color/btn_color" /> <corners android:radius="4dp" /> </shape> </item> </selector>
  8. Add a Style... Add a TextApperance… Add a color for

    text… Add an elevation for Kitkat... BUTTON BUTTON <ripple xmlns:android="http://schemas.android.com/apk/res/android" android:color="?android:attr/colorControlHighlight"> <item> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_pressed="true"> <shape> <solid android:color="@color/btn_color_pressed" /> <corners android:radius="4dp" /> </shape> </item> <item> <shape> <solid android:color="@color/btn_color" /> <corners android:radius="4dp" /> </shape> </item> </selector> </item> </ripple> Add a ripple effect
  9. Material Components

  10. • Use the canvas, custom views, custom drawables... • Spending

    a lot of time for building material components Material Components
  11. None
  12. Migrating to Material Components

  13. None
  14. None
  15. None
  16. Migrate from Support Library to Jetpack.

  17. -implementation ‘com.android.support:design:28.0.0’ +implementation ‘com.google.android.material:material:1.0.0’ Migrate to AndroidX +

  18. Create a brand new Material Theme

  19. We added a lib-design Android Library gradle module. dependencies {

    ... api 'com.google.android.material:material:1.3.0-alpha03' ... }
  20. Build the pillars of your design. Colors Typography Shapes

  21. colors.xml <?xml version="1.0" encoding="utf-8"?> <resources> <color name="app_icon_background">#0f2c55</color> <color name="mercury">#e2e2e2</color> <color

    name="mercury_light">#d1d1d1</color> <color name="mercury_dark">#e2e2e2</color> <color name="leaf">#689f38</color> <color name="leaf_light">#79af59</color> <color name="leaf_dark">#689f38</color> ... </resources>
  22. shapes.xml <?xml version="1.0" encoding="utf-8"?> <resources> <style name="ShapeAppearance.IO.SmallComponent" parent="ShapeAppearance.MaterialComponents.SmallComponent"> <item name="cornerFamily">rounded</item>

    <item name="cornerSize">@dimen/corner_radius_small</item> </style> <style name="ShapeAppearance.IO.MediumComponent" parent="ShapeAppearance.MaterialComponents.MediumComponent"> <item name="cornerFamily">rounded</item> <item name="cornerSize">0dp</item> </style> <style name="ShapeAppearance.IO.LargeComponent" parent="ShapeAppearance.MaterialComponents.LargeComponent"> <item name="cornerFamily">rounded</item> <item name="cornerSize">@dimen/corner_radius_large</item> </style> </resources>
  23. texts.xml <?xml version="1.0" encoding="utf-8"?> <resources> <style name="TextAppearance.IO.Headline1" parent="TextAppearance.MaterialComponents.Headline1" /> <style

    name="TextAppearance.IO.Headline2" parent="TextAppearance.MaterialComponents.Headline2" /> <style name="TextAppearance.IO.Headline3" parent="TextAppearance.MaterialComponents.Headline3" /> <style name="TextAppearance.IO.Headline4" parent="TextAppearance.MaterialComponents.Headline4" /> <style name="TextAppearance.IO.Headline5" parent="TextAppearance.MaterialComponents.Headline5" /> <style name="TextAppearance.IO.Headline6" parent="TextAppearance.MaterialComponents.Headline6" /> <style name="TextAppearance.IO.Subtitle1" parent="TextAppearance.MaterialComponents.Subtitle1" /> <style name="TextAppearance.IO.Subtitle2" parent="TextAppearance.MaterialComponents.Subtitle2" /> <style name="TextAppearance.IO.Body1" parent="TextAppearance.MaterialComponents.Body1" /> <style name="TextAppearance.IO.Body2" parent="TextAppearance.MaterialComponents.Body2" /> <style name="TextAppearance.IO.Button" parent="TextAppearance.MaterialComponents.Button" /> <style name="TextAppearance.IO.Caption" parent="TextAppearance.MaterialComponents.Caption" /> <style name="TextAppearance.IO.Overline" parent="TextAppearance.MaterialComponents.Overline" /> </resources>
  24. theme.xml <?xml version="1.0" encoding="utf-8"?> <resources> <!-- Base theme, all common

    styling here --> <style name="Base.IO" parent="@style/Theme.MaterialComponents.DayNight.NoActionBar"> <!-- Material shape attributes --> <item name="shapeAppearanceSmallComponent">@style/ShapeAppearance.IO.SmallComponent</item> <item name="shapeAppearanceMediumComponent">@style/ShapeAppearance.IO.MediumComponent</item> <item name="shapeAppearanceLargeComponent">@style/ShapeAppearance.IO.LargeComponent</item> <!--Material typo attributes--> <item name="textAppearanceHeadline1">@style/TextAppearance.IO.Headline1</item> ... <item name="textAppearanceOverline">@style/TextAppearance.IO.Overline</item </style> </resources>
  25. theme.xml <style name="IO" parent="@style/Base.IO"> <item name="colorPrimary">@color/slate</item> <item name="colorPrimaryDark">@color/slate_dark</item> <item name="colorSecondary">@color/grey_200</item>

    <item name="colorSecondaryVariant">@color/grey_400</item> <item name="colorSurface">@color/white</item> <item name="android:colorBackground">@color/white</item> <item name="divider">@color/divider</item> <item name="android:windowBackground">@color/white</item> </style>
  26. Update a View

  27. any_layout.xml <?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="wrap_content"

    android:padding="@dimen/spacing_small_medium" android:theme="@style/IO">
  28. Auto-inflation /** * An extension of {@link AppCompatViewInflater} that replaces

    some framework widgets with Material * Components ones at inflation time, provided a Material Components theme is in use. */ public class MaterialComponentsViewInflater extends AppCompatViewInflater
  29. Add new Components

  30. theme.xml <style name="Base.IO" parent="@style/Theme.MaterialComponents.DayNight.NoActionBar"> ... <!--Default styles--> <item name="cardViewStyle">@style/Widget.IO.CardView</item> <item

    name="materialButtonStyle">@style/Widget.IO.Button</item> <item name="snackbarStyle">@style/Widget.IO.Snackbar</item> <item name="switchStyle">@style/Widget.IO.Switch</item> <item name="textInputStyle">@style/Widget.IO.TextInputLayout</item> <item name="toolbarStyle">@style/Widget.IO.Toolbar</item> <!--Default overlays--> <item name="materialAlertDialogTheme"> @style/ThemeOverlay.IO.AlertDialog </item> </style>
  31. None
  32. None
  33. None
  34. None
  35. Remove old themes

  36. AndroidManifest.xml <activity android:name=".AdminActivity" android:theme="@style/zenittudetheme.light" /> <activity android:name=".LoginActivity" android:theme="@style/IO" />

  37. Migrating to Material Components Remove old theme Add new components

    Update a View Create a Material theme Migrate to AndroidX 1. Prepare 2. Iterate 3. Clean
  38. Build a Catalog app

  39. We added an app-design Android app gradle module. dependencies {

    ... implementation project(':lib-design') ... }
  40. None
  41. Material in action

  42. Add motion to your app

  43. Material Motion • Add meaningful motion to your application •

    Add nice transitions between Activities, Fragments or Views
  44. Material Motion // On Fragment A override fun onCreate(savedInstanceState: Bundle?)

    { super.onCreate(savedInstanceState) exitTransition = MaterialElevationScale(false).apply { duration = 300L } reenterTransition = MaterialElevationScale(true).apply { duration = 300L } } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) cover.transitionName = "unique_transition_name" name.transitionName = "another_unique_transition" }
  45. Material Motion // On Fragment B override fun onCreate(savedInstanceState: Bundle?)

    { postponeEnterTransition() // Might be useful for image transitions sharedElementEnterTransition = MaterialContainerTransform().apply { drawingViewId = R.id.nav_host_fragment duration = 300L fadeMode = MaterialContainerTransform.FADE_MODE_THROUGH interpolator = AccelerateDecelerateInterpolator() scrimColor = Color.TRANSPARENT } } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { binding.backdrop.transitionName = "unique_transition_name" binding.title.transitionName = "another_unique_transition" // Load your image async then start the transition with: startPostponedEnterTransition() }
  46. Material Motion // On Fragment A navigate to Fragment B

    val extras = FragmentNavigatorExtras( cover to film.episodeId.toString(), title to film.title) val action = MoviesFragmentDirections.actionMainFragmentToMovieFragment(film) findNavController().navigate(action, extras)
  47. None
  48. Material All The Things! Thank you!