MDC-111 Android: Incorporating Material Components into your codebase (Kotlin)

1. Introduction

logo_components_color_2x_web_96dp.png

Material Components (MDC) help developers implement Material Design. Created by a team of engineers and UX designers at Google, MDC features dozens of beautiful and functional UI components and is available for Android, iOS, web and Flutter.material.io/develop

Material Components for Android (MDC Android) isn't a new system or framework that requires a paradigm shift in your app. MDC Android is built on the same classes and APIs you already know in Android, such as AppCompat buttons and text fields. Components provided by MDC Android can be used as needed and make an immediate design improvement to your existing app.

What you'll build

In this codelab, you'll replace some existing components in a form with new ones by MDC.

MDC-Android components in this codelab

  • Text fields
  • Buttons
  • Menus

What you'll need

  • Basic knowledge of Android development
  • Android Studio (download it here if you don't already have it)
  • An Android emulator or device (available through Android Studio)
  • The sample code (see next step)

How would you rate your level of experience building Android apps?

Novice Intermediate Proficient

2. Set up your development environment

Download the starter codelab app

The starter app is located in the material-components-android-codelabs-111-starter/kotlin directory. Be sure to cd into that directory before beginning.

...or clone it from GitHub

To clone this codelab from GitHub, run the following commands:

git clone https://github.com/material-components/material-components-android-codelabs
cd material-components-android-codelabs/
git checkout 111-starter

Load the starter code in Android Studio

  1. Once the setup wizard finishes and the Welcome to Android Studio window is shown, click Open an existing Android Studio project. Navigate to the directory where you had installed the sample code, and select kotlin -> shipping (or search your computer for shipping) to open the Shipping project.
  2. Wait a moment for Android Studio to build and sync the project, as shown by activity indicators along the bottom of the Android Studio window.
  3. At this point, Android Studio might raise some build errors because you are missing the Android SDK or build tools, such as the one shown below. Follow the instructions in Android Studio to install/update these and sync your project.

2wEZ1kuSFwiRvi_vYXnYfwoQ5J79OVBi1SL6044ETje5cDT2rUHGy8ExjGxlBWlWuNUMf5tkLRUrr2_bz_0Im_JDvLyC-X-tNmBJvKUgsn8T4d11A1cq0ItqQl2n6DJrYKY-dEyRdw

Run the starter app

  1. Ensure that the build configuration to the left of the Run / Play button is app.
  2. Press the green Run / Play button to build and run the app.
  3. In the Select Deployment Target window, if you already have an Android device listed in your available devices, skip to Step 8. Otherwise, click Create New Virtual Device.
  4. In the Select Hardware screen, select a phone device, such as Pixel 2, and then click Next.
  5. In the System Image screen, select a recent Android version, preferably the highest API level. If it is not installed, click the Download link that is shown and complete the download.
  6. Click Next.
  7. On the Android Virtual Device (AVD) screen, leave the settings as they are and click Finish.
  8. Select an Android device from the deployment target dialog.
  9. Click Ok.
  10. Android Studio builds the app, deploys it, and automatically opens it on the target device.

Success! You should see the app and its form.

dba8e6132a12da58.png

3. Update the text fields

Material Design text fields have a major usability gain over plain text fields. By defining the hit zone with an outline or a background fill, users are more likely to interact with your form or identify text fields within more complicated content.

Import MDC-Android

Navigate to the app module's build.gradle file and make sure that the dependencies block includes a dependency on MDC Android:

api 'com.google.android.material:material:1.1.0-alpha05'

Replace text field styles

In shipping_info_activity.xml, add the following style to all TextInputLayout XML components:

shipping_info_activity.xml

style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"

Each TextInputLayout should look as follows:

shipping_info_activity.xml

<com.google.android.material.textfield.TextInputLayout
   android:id="@+id/name_text_input"
   style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   app:errorEnabled="true">

   <com.google.android.material.textfield.TextInputEditText
       android:id="@+id/name_edit_text"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:hint="@string/label_name" />
</com.google.android.material.textfield.TextInputLayout>

Build and run:

824c2b33592b2c7e.png

The text fields are all updated to use the newer designs in MDC.

Add an error

MDC text fields have built-in error presentation. MDC adds red text beneath your text field and updates decorations to be red too.

In ShippingInfoActivity.kt, update onCreate() to check the text input and set errors as appropriate. This should look something like this:

ShippingInfoActivity.kt

override fun onCreate(savedInstanceState: Bundle?) {
   super.onCreate(savedInstanceState)
   setContentView(R.layout.shipping_info_activity)

   val rootView = findViewById<View>(android.R.id.content)

   val textInputLayouts = Utils.findViewsWithType(
           rootView, TextInputLayout::class.java)

   save_button.setOnClickListener {
       var noErrors = true
       for (textInputLayout in textInputLayouts) {
           val editTextString = textInputLayout.editText!!.text.toString()
           if (editTextString.isEmpty()) {
               textInputLayout.error = resources.getString(R.string.error_string)
               noErrors = false
           } else {
               textInputLayout.error = null
           }
       }

       if (noErrors) {
           // All fields are valid!
       }
   }
}

Build and run. Press SAVE, but leave at least one text field empty:

ef2a846d08f2780d.png

The text fields that are empty are red and have error text beneath them.

4. Update the button

MDC has buttons with:

  • Ink ripples
  • Rounded corners
  • Theming support
  • Pixel-perfect layout and typography
  • Built on AppCompatButton (the standard Android button class) so you know how to use them in your code.

Optionally Replace button class

By default the Material library automatically inflates regular Buttons to MDC Buttons. However, you may optionally replace all references to Button with MaterialButton so that you can access additional methods that are available only in a MaterialButton such changing the corner radius. MDC Buttons are a simple plug-and-play component. You just replace the XML component name Button with MaterialButton, and apply the default MaterialButton style to the MaterialButton.

In shipping_info_activity.xml, change your button from:

shipping_info_activity.xml

<Button
   android:id="@+id/save_button"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:layout_gravity="end"
   android:layout_marginTop="16dp"
   android:text="@string/label_save" />

To:

shipping_info_activity.xml

<com.google.android.material.button.MaterialButton
   android:id="@+id/save_button"
   style="@style/Widget.MaterialComponents.Button"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:layout_gravity="end"
   android:layout_marginTop="16dp"
   android:text="@string/label_save" />

Build and run:

824c2b33592b2c7e.png

5. Add card

MaterialCardView is a component built on CardView with:

  • Correct elevation and styling
  • Stroke width and color attributes

Wrapping content in a card

Wrap your LinearLayout containing your content in shipping_info_activity.xml with a MaterialCardView component, as follows:

shipping_info_activity.xml

<com.google.android.material.card.MaterialCardView
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   android:layout_margin="16dp"
   app:contentPadding="16dp">


   <!-- LinearLayout goes here -->


</com.google.android.material.card.MaterialCardView>

Build and run. The entire form should be wrapped in a card:

75c86ab9fa395e3c.png

The Material Card View component is a familiar but fresh way to easily wrap your content in a card.

6. Recap

You've replaced some common components to show immediate value: text fields, buttons, cards, and you didn't have to do a whole redesign of your app. Other components can make a big difference too, such as the Top App Bar and TabLayout.

Next steps

You can explore even more components in MDC-Android by visiting the Android Widgets Catalog.

I was able to complete this codelab with a reasonable amount of time and effort

Strongly agree Agree Neutral Disagree Strongly disagree

I would like to continue using Material Components in the future

Strongly agree Agree Neutral Disagree Strongly disagree