5.2: Material Design

Contents:

Material Design is a visual design philosophy that Google created in 2014. The aim of Material Design is a unified user experience across platforms and device sizes. Material Design includes a set of guidelines for style, layout, motion, and other aspects of app design. The complete guidelines are available in the Material Design spec.

Material Design is for desktop web applications as well as for mobile apps. This chapter focuses only on Material Design for mobile apps on Android.

Principles of Material Design

In Material Design, elements in your Android app behave like real world materials: they cast shadows, occupy space, and interact with each other.

Bold, graphic, intentional

Material Design involves deliberate color choices, edge-to-edge imagery, large-scale typography, and intentional white space that create a bold and graphic interface.

Emphasize user actions in your app so that the user knows right away what to do, and how to do it. For example, highlight things that users can interact with, such as buttons, EditText fields, and switches.  Bright floating action button, noborder

In the above figure, #1 is a FloatingActionButton with a pink accent color.

Meaningful motion

Make animations and other motions in your app meaningful, so they don't happen at random. Use motions to reinforce the idea that the user is the app's primary mover. For example, design your app so that most motions are initiated by the user's actions, not by events outside the user's control. You can also use motion to focus the user's attention, give the user subtle feedback, or highlight an element of your app.

When your app presents an object to the user, make sure the motion doesn't break the continuity of the user's experience. For example, the user shouldn't have to wait for an animation or transition to complete.

The Motion section in this chapter goes into more detail about how to use motion in your app.

Colors

Material Design principles include the use of bold color.

Material Design color palette

The Material Design color palette contains colors to choose from, each with a primary color and shades labeled from 50 to 900:

  • Choose a color labeled "500" as the primary color for your brand. Use that color and shades of that color in your app.
  • Choose a contrasting color as your accent color and use it to create highlights in your app. Select any color that starts with "A".

When you create an Android project in Android Studio, a sample Material Design color scheme is selected for you and applied to your theme. In colors.xml in the values folder, three <color> elements are defined, colorPrimary, colorPrimaryDark, and colorAccent:

<resources>
    <color name="colorPrimary">#3F51B5</color>
    <!-- Indigo. -->
    <color name="colorPrimaryDark">#303F9F</color>
    <!-- A darker shade of indigo. -->
    <color name="colorAccent">#FF4081</color>
    <!-- A shade of pink. -->
</resources>

In styles.xml in the values folder, the three defined colors are applied to the default theme, which applies the colors to some app elements by default:

  • colorPrimary is used by several View elements by default. For example, in the AppTheme theme, colorPrimary is used as the background color for the action bar. Change this value to the "500" color that you select as your brand's primary color.
  • colorPrimaryDark is used in areas that need to slightly contrast with your primary color, for example the status bar above the app bar. Set this value to a slightly darker version of your primary color.
  • colorAccent is used as the highlight color for several View elements. It's also used for switches in the "on" position, FloatingActionButton, and more.

In the screenshot below, the background of the action bar uses colorPrimary (indigo), the status bar uses colorPrimaryDark (a darker shade of indigo), and the switch in the "on" position (#1 in the figure below) uses colorAccent (a shade of pink).  Bright switch, noborder

In summary, here's how to use the Material Design color palette in your Android app:

  1. Pick a primary color for your app from Material Design color palette and copy its hex value into the colorPrimary item in colors.xml.
  2. Pick a darker shade of this color and copy its hex value into the colorPrimaryDark item.
  3. Pick an accent color from the shades starting with an "A" and copy its hex value into the colorAccent item.
  4. If you need more colors, create additional <color> elements in the colors.xml file. For example, you could pick a lighter version of indigo and create an additional <color> element named colorPrimaryLight. (The name is up to you.)
     <color name="colorPrimaryLight">#9FA8DA</color>
     <!-- A lighter shade of indigo. -->
    
    To use this color, reference it as @color/colorPrimaryLight.

Changing the values in colors.xml automatically changes the colors of the View elements in your app, because the colors are applied to the theme in styles.xml.

Contrast

Make sure all the text in your app's UI contrasts with its background. Where you have a dark background, make the text on top of it a light color, and vice versa. This kind of contrast is important for readability and accessibility, because not all people see colors the same way.

If you use a platform theme such as Theme.AppCompat, contrast between text and its background is handled for you. For example:

  • If your theme inherits from Theme.AppCompat, the system assumes you are using a dark background. Therefore all of the text is near white by default.
  • If your theme inherits from Theme.AppCompat.Light, the text is near black, because the theme has a light background.
  • If you use the Theme.AppCompat.Light.DarkActionBar theme, the text in the action bar is near white, to contrast with the action bar's dark background. The rest of the text in the app is near black, to contrast with the light background.

Use color contrast to create visual separation among the elements in your app. Use your colorAccent color to call attention to key UI elements such as FloatingActionButton and switches in the "on" position.

Opacity

Your app can display text with different degrees of opacity to convey the relative importance of information. For example, text that's less important might be nearly transparent (low opacity).

Set the android:textColor attribute using any of these formats: "#rgb", "#rrggbb", "#argb", or "#aarrggbb". To set the opacity of text, use the "#argb" or "#aarrggbb" format and include a value for the alpha channel. The alpha channel is the a or the aa at the start of the textColor value.

The maximum opacity value, FF in hex, makes the color completely opaque. The minimum value, 00 in hex, makes the color complete transparent.

To determine what hex number to use in the alpha channel:

  1. Decide what level of opacity you want to use, as a percentage. The level of opacity used for text depends on whether your background is dark or light. To find out what level of opacity to use in different situations, see the Text color portion of the Material Design guide.
  2. Multiply that percentage, as a decimal value, by 255. For example, if you need primary text that's 87% opaque, multiply 0.87 x 255. The result is 221.85.
  3. Round the result to the nearest whole number: 222.
  4. Use a hex converter to convert the result to hex: DE. If the result is a single value, prefix it with 0.

In the following XML code, the background of the text is dark, and the color of the primary text is 87% white (deffffff). The first two numbers of the color code (de) indicate the opacity.

<TextView
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:text="Hello World!"
   android:textSize="45dp"
   android:background="@color/colorPrimaryDark"
   android:textColor="#deffffff"/>

Typography

The Android design language relies on traditional typographic tools such as scale, space, rhythm, and alignment with an underlying grid. Successful deployment of these tools is essential to help users quickly understand a screen of information. To support such use of typography, Android supplies a type family named Roboto, created specifically for the requirements of UI and high-resolution screens.

With Android 8.0 (API level 26), you can also choose to provide a font as a resource in XML that is bundled with the app package (APK), or download a font from a font provider app. These features are available on devices running Android API versions 14 and higher through the Support Library 26.

Typeface

Roboto is the standard Material Design typeface on Android. Roboto has six weights: Thin, Light, Regular, Medium, Bold, and Black.  Roboto font weights, noborder

Font styles

The Android platform provides predefined font styles and sizes that you can use in your app. These styles and sizes were developed to balance content density and reading comfort under typical conditions. Type sizes are specified with sp (scaleable pixels) to enable large type modes for accessibility.

Be careful not to use too many different type sizes and styles together in your layout.  Typographic styles, noborder

To use one of these predefined styles in a View, set the android:textAppearance attribute. This attribute defines the default appearance of the text: its color, typeface, size, and style. Use the backward-compatible TextAppearance.AppCompat style.

For example, to make a TextView appear in the Display 3 style, add the following attribute to the TextView in XML:

android:textAppearance="@style/TextAppearance.AppCompat.Display3"

For more information on styling text, view the Typography Material Design guidelines.

Fonts as resources

Android 8.0 (API level 26) introduces Fonts in XML, which lets you bundle fonts as resources in your app package (APK). You can create a font folder within the res folder as a resource directory using Android Studio, and then add a font XML file to the font folder. The fonts are compiled in your R file and are automatically available in Android Studio. To access a font resource, use @font/myfont, or R.font.myfont.

To use the Fonts in XML feature, the device that runs your app must run Android 8.0 (API level 26). To use the feature on devices running Android 4.1 (API level 16) and higher, use the Support Library 26. For more information on using the support library, refer to the Using the support library section.

To learn how to add fonts as XML resources, see Fonts in XML.

Downloadable fonts

An alternative to bundling fonts with the app package (APK) is to download the fonts from a provider app. Android 8.0 (API level 26) enables APIs to request fonts from a provider app, and the feature is available on devices running Android API versions 14 and higher through the Support Library 26. A font provider app is an app that retrieves fonts and caches them locally so that other apps can request and share fonts.

Downloadable fonts offer the following benefits:

  • Reduces the APK size.
  • Increases the app installation success rate.
  • Improves the overall system health, as multiple APKs can share the same font through a provider. This saves users cellular data, phone memory, and disk space. In this model, the font is fetched over the network when needed.

You can set your app to download fonts by using the layout editor in Android Studio 3.0. For detailed instructions, see Downloadable Fonts.

Layout

You specify View elements for your app's UI in layout resource files. Layout resources are written in XML and listed within the layout folder in the res folder in the Project > Android pane. The following guide explains some of the best practices for designing a layout.

Metrics

Components in the Material Design templates that are meant for mobile, tablet, and desktop devices align to an 8dp square grid. A dp is a density-independent pixel, an abstract unit based on screen density. A dp is similar to an sp, but sp is also scaled by the user's font size preference. That's why sp is preferred for accessibility.

The 8dp square grid guides the placement of elements in your layout. Every square in the grid is 8dp x 8dp, so the height and width of every element in the layout is a multiple of 8dp.  An 8dp square grid, noborder

In the above figure:

  1. The status bar in this layout is 24dp tall, the height of three grid squares.
  2. The toolbar is 56dp tall, the height of seven grid squares.
  3. One of the right-hand content margins is 16dp from the edge of the screen, the width of two grid squares.

Iconography in toolbars aligns to a 4dp square grid instead of an 8dp square grid, so the dimensions of icons in the toolbar are multiples of 4dp.

Keylines

Keylines are outlines in a layout grid that determine the placement of text and icons. For example, keylines mark the edges of the margins in a layout.  Keylines, noborder

In the above figure:

  1. Keyline showing the left margin for the screen edge, which in this case is 16dp.
  2. Keyline showing the left margin for content associated with an icon or avatar, 72dp.
  3. Keyline showing the right margin for the screen edge, 16dp.

Material Design typography aligns to a 4dp baseline grid, which is a grid made up only of horizontal lines.

To learn more about metrics and keylines in Material Design, visit the metrics and keylines guide.

Components and patterns

Button elements and many other View elements used in Android conform by default to Material Design principles. The Material Design guide includes components and patterns that you can build on to help your users intuit how the elements in your UI work, even if users are new to your app.

Use Material Design components to guide the specs and behavior of buttons, chips, cards, and many other UI elements. Use Material Design patterns to guide how you format dates and times, gestures, the navigation drawer, and many other aspects of your UI.

This section teaches you about the Design Support Library and some of the components and patterns that are available to you. For complete documentation about all the components and patterns that you can use, see the Material Design guide.

Design Support Library

The Design package provides APIs to support adding Material Design components and patterns to your apps. The Design Support Library adds support for various Material Design components and patterns for you to build on. To use the library, include the following dependency in your build.gradle (Module: app) file:

compile 'com.android.support:design:26.1.0'

To make sure you have the most recent version number for the Design Support Library, check the Support Library page.

Floating action buttons (FABs)

Use a floating action button (FAB) for actions you want to encourage users to take. A FAB is a circled icon that floats "above" the UI. On focus it changes color slightly, and it appears to lift up when selected. When tapped, it can contain related actions.  Floating action button (FAB), noborder

In this figure:

  1. A normal-sized FAB

To implement a FAB, use FloatingActionButton and set the FAB's attributes in your layout XML. For example:

<android.support.design.widget.FloatingActionButton
    android:id="@+id/addNewItemFAB"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/ic_plus_sign"
    app:fabSize="normal"
    app:elevation="10%" />

The fabSize attribute sets the FAB's size. It can be "normal" (56dp), "mini" (40dp), or "auto", which changes based on the window size.

The FAB's elevation is the distance between its surface and the depth of its shadow. You can set the elevation attribute as a reference to another resource, a string, a boolean, or several other ways.

To learn about all the attributes you can set for a FAB including clickable, rippleColor, and backgroundTint, see FloatingActionButton. To make sure you're using FABs as intended, check the extensive FAB usage information in the Material Design guide.

A navigation drawer is a panel that slides in from the left and contains navigation destinations for your app. A navigation drawer (shown as #1 in the figure below) spans the height of the screen, and everything behind it is visible, but darkened.  Navigation drawer example, noborder

To implement a navigation drawer, use the DrawerLayout APIs available in the Support Library.

In your XML, use a DrawerLayout object as the root view of your layout. Inside it, add two views, one for your primary layout when the drawer is hidden, and one for the contents of the drawer.

For example, the following layout has two child views: a FrameLayout to contain the main content (populated by a Fragment at runtime), and a ListView for the navigation drawer.

<android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <!-- The main content view -->
    <FrameLayout
        android:id="@+id/content_frame"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
    <!-- The navigation drawer -->
    <ListView android:id="@+id/left_drawer"
        android:layout_width="240dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:choiceMode="singleChoice"
        android:divider="@android:color/transparent"
        android:dividerHeight="0dp"
        android:background="#111"/>
</android.support.v4.widget.DrawerLayout>

The lesson on user navigation in this course provides a complete example of using a DrawerLayout. For more information, see Creating a Navigation Drawer and the usage information in the Material Design guide.

Snackbars

A snackbar provides brief feedback about an operation through a message in a horizontal bar on the screen. It contains a single line of text directly related to the operation performed. A snackbar (shown as #1 in the figure below) can contain a text action, but no icons.  Snackbar message, noborder

Snackbars automatically disappear after a timeout or after a user interaction elsewhere on the screen. You can associate a snackbar with any kind of view (any object derived from the View class). However, if you associate the snackbar with a CoordinatorLayout, the snackbar gains additional features:

  • The user can dismiss the snackbar by swiping it away.
  • The layout moves some other UI elements when the snackbar appears. For example, if the layout has a FAB, the layout moves the FAB up when it shows the snackbar, instead of drawing the snackbar on top of the FAB.

To create a Snackbar object, use the Snackbar.make() method. Specify the ID of the CoordinatorLayout to use for the snackbar, the message that the snackbar displays, and the length of time to show the message. For example, this statement creates the snackbar and calls show() to show the snackbar to the user:

Snackbar.make(findViewById(R.id.myCoordinatorLayout),
               R.string.email_sent,Snackbar.LENGTH_SHORT).show;

For more information, see Building and Displaying a Pop-Up Message and the Snackbar reference. To make sure you're using snackbars as intended, see the snackbar usage information in the Material Design guide.

Tip: A Toast is similar to a Snackbar, except that a Toast is usually used for a system message, and a Toast can't be swiped off the screen.

Tabs

Use tabs to organize content at a high level. For example, the user might use tabs to switch between View elements, data sets, or functional aspects of an app. Present tabs as a single row above their associated content. Make tab labels short and informative. For example, in the figure below, the app shows three tabs (marked by #1), with the All tab selected.  Example of tabs, noborder

You can you use tabs with swipe views in which users navigate between tabs with a horizontal finger gesture (horizontal paging). If your tabs use swipe views, don't pair the tabs with content that also supports swiping. For an example, see the lesson in this course on providing user navigation.

For information on implementing tabs, see Creating Swipe Views with Tabs. To make sure you're using tabs as intended, see the extensive tab usage information in the Material Design guide.

Cards

A card is a sheet of material that serves as an entry point to more detailed information. Each card covers only one subject. A card may contain a photo, text, and a link. It can display content containing elements of varying size, such as photos with captions of variable length.

A card collection is a layout of cards on the same plane. The figure below shows one card in a card collection (marked by #1).  Example of a card, noborder

CardView is included as part of the v7 support library. To use the library, include the following dependency in your build.gradle (Module: app) file:

compile 'com.android.support:cardview-v7:26.1.0'

Lists

A list is a single continuous column of rows of equal width. Each row functions as a container for a tile. Tiles hold content, and can vary in height within a list.  Example of a list, noborder

In the figure above:

  1. A tile within the list
  2. A list with rows of equal width, each containing a tile

To create a list, use the RecyclerView widget. include the following dependency in your build.gradle (Module: app) file:

compile 'com.android.support:recyclerview-v7:26.1.0'

For more information on creating lists in Android, see Create a List with RecyclerView.

Motion

Motion in the world of Material Design is used to describe spatial relationships, functionality, and intention with beauty and fluidity. Motion shows how an app is organized and what it can do.

Motion in Material Design must be:

  1. Responsive. It quickly responds to user input precisely where the user triggers it.
  2. Natural. Movement is inspired by forces in the natural world. For example, real-world forces like gravity inspire an element's movement along an arc rather than in a straight line.  Example of natural forces, noborder

  3. Aware. Material is aware of its surroundings, including the user and other material around it. Objects can be attracted to other objects in the UI, and they respond appropriately to user intent. As elements transition into view, their movement is choreographed in a way that defines their relationships.  Example of aware transition, noborder

  4. Intentional. Movement guides the user's focus to the right place at the right time. Movement can communicate different signals, such as whether an action is unavailable.  Example of animation used to define actions, noborder

To put these principles into practice in Android, use animations and transitions.

Animations

There are three ways you can create animation in your app:

  • Property animation changes an object's properties over a specified period of time.The property animation system was introduced in Android 3.0 (API level 11). Property animation is more flexible than View animation, and it offers more features.
  • View animation calculates animation using start points, endpoints, rotation, and other aspects of animation. The Android view animation system is older than the property animation system and can only be used for View elements. It's relatively easy to set up and offers enough capabilities for many use cases.
  • Drawable animation lets you load a series of drawable resources one after another to create an animation. Drawable animation is useful if you want to animate things that are easier to represent with drawable resources, such as a progression of bitmap images.

For complete details about these three types for animation, see the Animation and Graphics Overview.

The Material Design theme provides some default animations for touch feedback and activity transitions. The animation APIs let you create custom animations for touch feedback in UI controls, changes in view state, and activity transitions.

Touch feedback

Touch feedback provides instant visual confirmation at the point of contact when a user interacts with a UI element. The default touch feedback animation for a Button uses the RippleDrawable class, which transitions between different states with a ripple effect.

In this example, ripples of ink expand outward from the point of touch to confirm user input. The card "lifts" and casts a shadow to indicate an active state:  Example of touch feedback, noborder

In most cases, you apply ripple functionality in your view XML by specifying the view background as follows:

  • ?android:attr/selectableItemBackground for a bounded ripple.
  • ?android:attr/selectableItemBackgroundBorderless for a ripple that extends beyond the View. It is drawn upon, and bounded by, the nearest parent of the View with a non-null background.
Note: The selectableItemBackgroundBorderless attribute was introduced in API level 21.

Alternatively, you can define a RippleDrawable as an XML resource using the <ripple> element.

You can assign a color to RippleDrawable objects. To change the default touch feedback color, use the theme's android:colorControlHighlight attribute.

Circular reveal

A reveal animation shows or hides a group of UI elements by animating the clipping boundaries for a View. In circular reveal, you reveal or hide a View by animating a clipping circle. (A clipping circle is a circle that crops or hides the part of an image that's outside the circle.)

To animate a clipping circle, use the ViewAnimationUtils.createCircularReveal() method. For example, here's how to reveal a previously invisible view using circular reveal:

// Previously invisible view
View myView = findViewById(R.id.my_view);

// Get the center for the clipping circle.
int cx = myView.getWidth() / 2;
int cy = myView.getHeight() / 2;

// Get the final radius for the clipping circle.
float finalRadius = (float) Math.hypot(cx, cy);

// Create the animator for this view (the start radius is zero).
Animator anim = ViewAnimationUtils
               .createCircularReveal(myView, cx, cy, 0, finalRadius);

// Make the view visible and start the animation.
myView.setVisibility(View.VISIBLE);
anim.start();

Here's how to hide a previously visible View using circular reveal:

// Previously visible view
final View myView = findViewById(R.id.my_view);

// Get the center for the clipping circle.
int cx = myView.getWidth() / 2;
int cy = myView.getHeight() / 2;

// Get the initial radius for the clipping circle.
float initialRadius = (float) Math.hypot(cx, cy);

// Create the animation (the final radius is zero.
Animator anim = ViewAnimationUtils.
              createCircularReveal(myView, cx, cy, initialRadius, 0);

// Make the view invisible when the animation is done.
anim.addListener(new AnimatorListenerAdapter() {
    @Override
    public void onAnimationEnd(Animator animation) {
        super.onAnimationEnd(animation);
        myView.setVisibility(View.INVISIBLE);
    }
});

// Start the animation.
anim.start();

Activity transitions

Activity transitions are animations that provide visual connections between different states in your UI. You can specify custom animations for enter and exit transitions, and for transitions of shared elements between activities.

  • An enter transition determines how View elements in an Activity enter the scene. For example in an explode enter transition, View elements enter the scene from the outside and fly towards the center of the screen.
  • An exit transition determines how View elements in an Activity exit the scene. For example in an explode exit transition, View elements exit the scene by moving away from the center.
  • A shared elements transition determines how View elements that are shared between two activities transition between these activities. For example, if two activities have the same image in different positions and sizes, the changeImageTransform shared element transition translates and scales the image smoothly between these activities.

To use these transitions, set transition attributes in a <style> element in your XML. The following example creates a theme named BaseAppTheme that inherits one of the Material Design themes. The BaseAppTheme theme uses all three types of Activity transitions:

<style name="BaseAppTheme" parent="android:Theme.Material">
  <!-- enable window content transitions -->
  <item name="android:windowActivityTransitions">true</item>

  <!-- specify enter and exit transitions -->
  <item name="android:windowEnterTransition">@transition/explode</item>
  <item name="android:windowExitTransition">@transition/explode</item>

  <!-- specify shared element transitions -->
  <item name="android:windowSharedElementEnterTransition">
    @transition/change_image_transform</item>
  <item name="android:windowSharedElementExitTransition">
    @transition/change_image_transform</item>
</style>

The change_image_transform transition in this example is defined as follows:

<!-- res/transition/change_image_transform.xml -->
<!-- (see also Shared Transitions below) -->
<transitionSet xmlns:android="http://schemas.android.com/apk/res/android">
  <changeImageTransform/>
</transitionSet>

The changeImageTransform element corresponds to the ChangeImageTransform class. For more information, see the API reference for Transition.

To enable window content transitions in your Java code instead, call the Window.requestFeature() method:

// Inside your activity
// (if you did not enable transitions in your theme)
getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);

// Set an exit transition
getWindow().setExitTransition(new Explode());

 Example of a shared element transition, noborder

To specify transitions in your code, call the following methods with a Transition object:

  • Window.setEnterTransition()
  • Window.setExitTransition()
  • Window.setSharedElementEnterTransition()
  • Window.setSharedElementExitTransition()

For details about these methods, see Window.

To start an activity that uses transitions, use the ActivityOptions.makeSceneTransitionAnimation() method.

For more about implementing transitions in your app, see Start an Activity with an Animation.

Curved motion

In Android 5.0 (API level 21) and newer, you can define custom timing curves and curved motion patterns for animations. To do this, use the PathInterpolator class, which interpolates an object's path based on a Bézier curve or a Path object. The interpolator specifies a motion curve in a 1x1 square, with anchor points at (0,0) and (1,1) and control points that you specify using the constructor arguments. You can also define a path interpolator as an XML resource:

<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
    android:controlX1="0.4"
    android:controlY1="0"
    android:controlX2="1"
    android:controlY2="1"/

The system provides XML resources for the three basic curves in the Material Design specification:

  • @interpolator/fast_out_linear_in.xml
  • @interpolator/fast_out_slow_in.xml
  • @interpolator/linear_out_slow_in.xml

To use a PathInterpolator object, pass it to the Animator.setInterpolator() method.

The ObjectAnimator class has constructors you can use to animate coordinates along a path using two or more properties at once. For example, the following code uses a Path object to animate the X and Y properties of a View:

ObjectAnimator mAnimator;
mAnimator = ObjectAnimator.ofFloat(view, View.X, View.Y, path);
// ... Rest of code
mAnimator.start();

Other custom animations

Other custom animations are possible, including animated state changes (using the StateListAnimator class) and animated vector drawables (using the AnimatedVectorDrawable class). For complete details, see Defining Custom Animations.

The related practical is 5.2: Cards and colors.

Learn more

Android Studio documentation:

Android developer documentation:

Material Design:

Android Developers Blog: Android Design Support Library

Material Design

results matching ""

    No results matching ""