Material Design

Shape Theming

Material Design encourages brand expression through shapes. The Material Components library offers a shape library that can be used to create non-standard shapes.

The shape library provides a MaterialShapeDrawable class that can draw custom shapes while taking shadows, elevation, scale and color into account.

Design & API Documentation

Usage

MaterialShapeDrawable draws itself using a path generated by provided CornerTreatments and EdgeTreatments. The shape library provides some subclassed CornerTreatments and EdgeTreatments to allow for easily building new shapes:

  • CutCornerTreatment
  • RoundedCornerTreatment
  • TriangleEdgeTreatment

Both CornerTreatment and EdgeTreatment can be subclassed to create custom corners and edges.

Note: The shape library is experimental and subject to change.

Coming Soon

We will be adding theming support for shapes to make the shapes of components themeable at the application level. This will allow an app to change shapes of components inside their apps just by specifying shape theme attributes.

Here’s an example of what this might look like: Let’s say you want to change the corners in your app to cut corners. You’d be able to specify attributes like cornerStylePrimary and cornerRadiusPrimary at the theme level. This might look something like this:

<style name="Theme.MyApp" parent="Theme.MaterialComponents.Light">
  ...
  <item name="cornerRadiusPrimary">8dp</item>
  <item name="cornerStylePrimary">cut</item>
  <item name="cornerRadiusSecondary">4dp</item>
  <item name="cornerStyleSecondary">cut</item>
  ...
</style>

Then, Material components would read in those theme attributes and style themselves accordingly.

If you want to change a component’s corner style mapping, you’d be able to change the component’s style across the app. Let’s say you wanted to modify MaterialCardView so that it uses cornerRadiusSecondary instead of cornerRadiusPrimary. All you’d have to do is define your own card style that extends from the widget’s style, and set the component’s relevant attributes to the desired theme attributes:

<style name="Widget.MyApp.MyCard" parent="Widget.MaterialComponents.MaterialCardView">
  <item name="cardCornerRadius">?attr/cornerRadiusSecondary</item>
</style>

And set the mapping to the custom component style in the theme:

<style name="Theme.MyApp" parent="Theme.MaterialComponents.Light">
  ...
  <item name="materialCardViewStyle">@style/Widget.MyApp.MyCard</item>
  ...
</style>

This would apply the card corner attributes specified in Widget.MyApp.MyCard to all cards in the app. You can also set this style on individual components in your layout file:

    <com.google.android.material.card.MaterialCardView
        style="@style/Widget.MyApp.MyCard"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="@dimen/mtrl_card_spacing"
        android:layout_marginTop="@dimen/mtrl_card_spacing"
        android:layout_marginRight="@dimen/mtrl_card_spacing"
        android:minHeight="@dimen/cat_card_demo_min_height">
      <TextView
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:text="@string/card_text"/>
    </com.google.android.material.card.MaterialCardView>

Or you can set the attributes on the widget in your layout file to override the default behavior on a case-by-case basis:

    <com.google.android.material.card.MaterialCardView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="@dimen/mtrl_card_spacing"
        android:layout_marginTop="@dimen/mtrl_card_spacing"
        android:layout_marginRight="@dimen/mtrl_card_spacing"
        android:minHeight="@dimen/cat_card_demo_min_height"
        app:cardCornerRadius="?attr/cornerRadiusSecondary">
      <TextView
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:text="@string/card_text"/>
    </com.google.android.material.card.MaterialCardView>