Implementing Material Design
1. Using Material Components
Material Components for Android provide a set of UI elements that follow Google's Material Design guidelines. These components help developers build consistent, visually appealing interfaces with minimal effort.
| Component | Description | Usage | Notes |
|---|---|---|---|
| Button | Standard button with Material Design styling | com.google.android.material.button.MaterialButton |
Supports elevation, ripple effects, and custom shapes |
| CardView | Material-style card with elevation and rounded corners | com.google.android.material.card.MaterialCardView |
Can include content, images, and actions |
| TextField | Text input field with Material Design styling and validation | com.google.android.material.textfield.TextInputLayout |
Supports floating labels, error states, and helper text |
| BottomSheet | Material-style bottom sheet that slides up from the bottom | com.google.android.material.bottomsheet.BottomSheetDialog |
Can be modal or non-modal; supports peek and expand states |
| FloatingActionButton | Round button that floats above the main content | com.google.android.material.floatingactionbutton.FloatingActionButton |
Commonly used for primary actions; supports animations |
Example: Using MaterialButton
<com.google.android.material.button.MaterialButton
android:id="@+id/material_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Click Me"
app:backgroundTint="@color/colorPrimary"
app:cornerRadius="8dp" />
Example: Using TextInputLayout
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Enter your name"
app:boxStrokeColor="@color/colorPrimary">
<com.google.android.material.textfield.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</com.google.android.material.textfield.TextInputLayout>
Note: Material Components require the
MaterialTheme to be applied in your app's theme. Ensure that you extend Theme.Material3.DayNight or similar in your styles.xml.
Warning: Avoid mixing Material Components with older Android UI components (e.g.,
Button from android.widget) as it can lead to inconsistent styling and layout issues.
2. Implementing App Bar
| Property | Description | Values |
|---|---|---|
| android:title | Title of the App Bar | string |
| android:subtitle | Subtitle of the App Bar | string |
| app:layout_scrollFlags | Defines how the App Bar behaves during scroll | scroll, exitUntilCollapsed, enterAlways, enterAlwaysCollapsed |
Example: Basic App Bar
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.appbar.MaterialToolbar
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:title="My App"
app:subtitle="Welcome" />
</com.google.android.material.appbar.AppBarLayout>
Example: App Bar with Navigation Icon
<com.google.android.material.appbar.MaterialToolbar
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:title="Home"
app:navigationIcon="@drawable/ic_menu"
app:menu="@menu/top_app_bar" />
Note: The
MaterialToolbar is preferred over the older Toolbar for Material Design implementations.
Warning: Ensure that the
AppBarLayout is a direct parent of the MaterialToolbar to maintain proper behavior.
3. Using Bottom Navigation
| Property | Description | Values |
|---|---|---|
| app:menu | Specifies the menu resource file to use for the navigation items | R.menu.bottom_navigation_menu |
| app:backgroundTint | Sets the background color of the bottom navigation bar | ?android:attr/colorPrimary |
| app:labelVisibilityMode | Controls whether labels are shown for navigation items | auto, selected, labeled, unlabeled |
Example: Bottom Navigation Setup
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val bottomNav = findViewById<BottomNavigationView>(R.id.bottom_navigation)
bottomNav.setOnItemSelectedListener { item ->
when (item.itemId) {
R.id.nav_home -> {
// Handle home navigation
true
}
R.id.nav_profile -> {
// Handle profile navigation
true
}
else -> false
}
}
}
}
Example: Menu Resource
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/nav_home"
android:icon="@drawable/ic_home"
android:title="Home" />
<item
android:id="@+id/nav_profile"
android:icon="@drawable/ic_profile"
android:title="Profile" />
</menu>
Note: The
labelVisibilityMode property can be set to auto to show labels only when the item is selected or when there are fewer than three items.
4. Implementing Navigation Drawer
| Property | Description | Values |
|---|---|---|
| app:headerLayout | Layout resource for the header of the navigation drawer | layout/navigation_header |
| app:menu | Menu resource file defining drawer items | menu/navigation_menu |
Example: Navigation Drawer Setup
class MainActivity : AppCompatActivity() {
private lateinit var drawerLayout: DrawerLayout
private lateinit var navView: NavigationView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
drawerLayout = findViewById(R.id.drawer_layout)
navView = findViewById(R.id.nav_view)
val toggle = ActionBarDrawerToggle(
this, drawerLayout, R.string.open_drawer, R.string.close_drawer
)
drawerLayout.addDrawerListener(toggle)
toggle.syncState()
navView.setNavigationItemSelectedListener { item ->
when (item.itemId) {
R.id.nav_home -> {
// Handle home action
true
}
else -> false
}
}
}
}
Note: Ensure the
DrawerLayout has a NavigationView as its direct child.
Key Steps to Implement Navigation Drawer
- Create a
DrawerLayoutin your layout XML - Add a
NavigationViewas a child of the drawer layout - Define menu items in
res/menu/navigation_menu.xml - Set up
ActionBarDrawerTogglefor toggle functionality - Implement
NavigationItemSelectedListenerto handle item clicks
5. Working with Floating Action Button
| Property | Values | Description |
|---|---|---|
| android:src | @drawable/ic_add |
Icon resource for the FAB |
| app:tint | ?attr/colorOnPrimary |
Color of the FAB icon |
| app:fabSize | normal, mini |
Size of the FAB (default: normal) |
| app:elevation | 6dp |
Shadow elevation for the FAB |
Example: Basic FAB Usage
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="16dp"
android:src="@drawable/ic_add"
app:tint="?attr/colorOnPrimary"
app:fabSize="normal"
app:elevation="6dp" />
Example: FAB with Click Listener
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val fab = findViewById<FloatingActionButton>(R.id.fab)
fab.setOnClickListener {
// Handle FAB click
Toast.makeText(this, "FAB clicked", Toast.LENGTH_SHORT).show()
}
}
}
Note: FABs are typically used for primary actions in the app, such as creating a new item or initiating a key workflow.
6. Using Material Dialogs
Material dialogs are used to display important information or prompt user actions. They can be modal or non-modal and come in various styles like simple, list, and alert.
| Property | Description | Values |
|---|---|---|
| title | Dialog title text | String |
| message | Dialog message content | String |
| positiveButtonText | Text for positive button | String |
| negativeButtonText | Text for negative button | String |
| neutralButtonText | Text for neutral button | String |
| cancelable | Whether dialog can be dismissed by tapping outside | Boolean |
Example: Basic Material Dialog
val builder = AlertDialog.Builder(this)
builder.setTitle("Alert")
builder.setMessage("This is a Material Dialog")
builder.setPositiveButton("OK") { dialog, _ ->
// Handle positive button click
}
builder.setNegativeButton("Cancel") { dialog, _ ->
// Handle negative button click
}
val dialog = builder.create()
dialog.show()
Example: Dialog with List Items
val items = arrayOf("Item 1", "Item 2", "Item 3")
val builder = AlertDialog.Builder(this)
builder.setTitle("Choose an item")
builder.setItems(items) { dialog, which ->
// Handle item selection
val selectedItem = items[which]
}
val dialog = builder.create()
dialog.show()
Note: Material dialogs are part of the
androidx.appcompat library and require a theme that extends Theme.MaterialComponents.
7. Implementing Snackbar
Example: Basic Snackbar
val snackbar = Snackbar.make(
findViewById(R.id.coordinator_layout),
"This is a Snackbar",
Snackbar.LENGTH_SHORT
)
snackbar.show()
| Property | Description | Values |
|---|---|---|
| view | Parent view to show the Snackbar on | View |
| message | Text to display in the Snackbar | CharSequence |
| duration | How long to show the Snackbar | LENGTH_SHORT, LENGTH_LONG, LENGTH_INDEFINITE |
Example: Snackbar with Action
val snackbar = Snackbar.make(
findViewById(R.id.coordinator_layout),
"Item deleted",
Snackbar.LENGTH_LONG
)
snackbar.setAction("Undo") {
// Handle undo action
}
snackbar.show()
| Property | Description | Values |
|---|---|---|
| actionText | Text for the action button | CharSequence |
| actionListener | Callback when action is clicked | View.OnClickListener |
Example: Customizing Snackbar Appearance
val snackbar = Snackbar.make(
findViewById(R.id.coordinator_layout),
"Custom Snackbar",
Snackbar.LENGTH_SHORT
)
snackbar.setBackgroundTint(Color.RED)
snackbar.setTextColor(Color.WHITE)
snackbar.show()
| Property | Description | Values |
|---|---|---|
| backgroundTint | Background color of the Snackbar | ColorInt |
| textColor | Text color of the Snackbar message | ColorInt |
8. Using Chips
Chips are compact elements that represent an input, attribute, or action. They are used to display multiple selections or tags in a compact format.
| Property | Description | Values |
|---|---|---|
| chipBackgroundColor | Background color of the chip | ColorStateList |
| chipStrokeColor | Color of the chip's stroke | ColorStateList |
| chipStrokeWidth | Width of the chip's stroke | Dimension |
| chipIcon | Icon to display in the chip | Drawable |
| chipIconTint | Tint color for the chip icon | ColorStateList |
| chipIconSize | Size of the chip icon | Dimension |
Example: Basic Chip
val chip = Chip(this)
chip.text = "Example Chip"
chip.setChipBackgroundColorResource(R.color.chip_background)
Example: Chip with Icon
val chip = Chip(this)
chip.text = "Chip with Icon"
chip.chipIcon = ContextCompat.getDrawable(this, R.drawable.ic_star)
chip.chipIconTint = ColorStateList.valueOf(Color.YELLOW)
Note: Chips can be used in a
ChipGroup to create a set of related chips.
Warning: Ensure that the chip's text and icon are accessible to users with visual impairments.
Chip Usage Guidelines
- Use chips for tags, selections, or actions.
- Chips can be interactive or non-interactive.
- Use appropriate colors and icons to convey meaning.
9. Implementing Bottom Sheets
| Property | Description | Values |
|---|---|---|
| behavior | Defines the behavior of the bottom sheet | hideable, peekHeight, expanded |
| peekHeight | Height of the bottom sheet when collapsed | dp value or match_parent |
| state | Current state of the bottom sheet | collapsed, expanded, hidden |
Example: BottomSheetBehavior
val bottomSheetBehavior = BottomSheetBehavior.from(bottomSheetView)
bottomSheetBehavior.state = BottomSheetBehavior.STATE_EXPANDED
Example: Layout Configuration
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent" />
<com.google.android.material.bottomsheet.BottomSheetLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:behavior_peekHeight="100dp"
app:behavior_hideable="true"
app:layout_behavior="@string/bottom_sheet_behavior" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
Note: The
BottomSheetBehavior is part of Material Design Components and requires the com.google.android.material:material dependency.
Warning: Ensure that the
layout_behavior attribute is correctly set to @string/bottom_sheet_behavior for proper functionality.
10. Applying Material Theming
| Property | Values | Description |
|---|---|---|
| colorPrimary | @color/primary |
Primary color for the app's theme |
| colorOnPrimary | @color/onPrimary |
Color used for content on top of primary color |
| colorSecondary | @color/secondary |
Secondary color for the app's theme |
| colorOnSecondary | @color/onSecondary |
Color used for content on top of secondary color |
| colorSurface | @color/surface |
Color for surfaces like cards and dialogs |
| colorOnSurface | @color/onSurface |
Color used for content on top of surface color |
Example: Define Material Theme Colors in res/values/colors.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="primary">#6200EE</color>
<color name="onPrimary">#FFFFFF</color>
<color name="secondary">#03DAC5</color>
<color name="onSecondary">#000000</color>
<color name="surface">#FFFFFF</color>
<color name="onSurface">#000000</color>
</resources>
Example: Apply Theme in res/values/themes.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="AppTheme" parent="Theme.MaterialComponents.DayNight">
<item name="colorPrimary">@color/primary</item>
<item name="colorOnPrimary">@color/onPrimary</item>
<item name="colorSecondary">@color/secondary</item>
<item name="colorOnSecondary">@color/onSecondary</item>
<item name="colorSurface">@color/surface</item>
<item name="colorOnSurface">@color/onSurface</item>
</style>
</resources>
Note: Material Design themes in Android use
Theme.MaterialComponents as the base style.
Warning: Ensure that color contrast meets accessibility guidelines (WCAG 2.1).
11. Using Material You Dynamic Colors
Material You introduces dynamic color theming, which uses the user's wallpaper to generate a color palette for the app.
| Property | Description | Values |
|---|---|---|
| android:colorPrimary | Primary color for app elements | ?attr/colorPrimary |
| android:colorOnPrimary | Color for content on primary elements | ?attr/colorOnPrimary |
| android:colorSecondary | Secondary color for app elements | ?attr/colorSecondary |
| android:colorOnSecondary | Color for content on secondary elements | ?attr/colorOnSecondary |
Example: Applying Dynamic Colors in Theme
<style name="Theme.MyApp" parent="Theme.Material3.DayNight">
<item name="colorPrimary">?attr/colorPrimary</item>
<item name="colorOnPrimary">?attr/colorOnPrimary</item>
<item name="colorSecondary">?attr/colorSecondary</item>
<item name="colorOnSecondary">?attr/colorOnSecondary</item>
</style>
Note: Dynamic colors are supported on Android 12 (API level 31) and higher.
Warning: Ensure that your app's color scheme remains accessible when using dynamic colors.
| Feature | Support | Notes |
|---|---|---|
| Dynamic Color | Supported | Available on Android 12+ |
| Custom Palette | Partially | Can be customized but not fully dynamic |