Material 3 BadgeDrawable
Overview
BadgeDrawable displays dynamic notifications or counts.
Material 3 BadgeDrawable
shows status, counts, or notifications (e.g., unread messages) on components like BottomNavigationView
or TabLayout
. It supports two variants (Small and Large) with three types (Icon-only, With Number, With Text), configurable via attributes or programmatically. This guide covers implementation, accessibility, and theming, noting limited theme attribute support.


Getting Started
- Add Material Components for Android library dependency
- Create with
BadgeDrawable.create(Context)
- Attach using
BadgeUtils.attachBadgeDrawable
- Use with
Theme.Material3.*
for styling
Accessibility
- Set content descriptions (e.g.,
setContentDescriptionForText
) for TalkBack - Use
setContentDescriptionQuantityStringsResource
for numeric badges - Ensure sufficient contrast for visibility
Configuration and Behavior
- Configure gravity (
TOP_END
,TOP_START
) - Adjust offsets with
setHorizontalOffset
,setVerticalOffset
- Set number or text with
setNumber
,setBadgeText
- Auto-moves within ancestor bounds to avoid clipping
val badgeDrawable = BadgeDrawable.create(context)
badgeDrawable.badgeGravity = BadgeDrawable.TOP_END
badgeDrawable.number = 99
badgeDrawable.setContentDescriptionQuantityStringsResource(R.plurals.badge_count)
Badge Types
- Icon-only Badge: Small dot for subtle alerts
- Badge with Number: Numeric count (e.g., unread messages)
- Badge with Text: Short text or capped numbers (e.g., "999+")

Small Badge

- Icon-only dot for minimal notifications
- Ideal for subtle status indicators
Example
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottom_navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
app:menu="@menu/bottom_nav_menu"/>
val badgeDrawable = BadgeDrawable.create(context)
val anchorView = bottomNavigation.findViewById<View>(R.id.nav_item)
BadgeUtils.attachBadgeDrawable(badgeDrawable, anchorView)
badgeDrawable.setContentDescriptionNumberless("New notification")
Small Badge Anatomy

Component | Description | Behavior |
---|---|---|
Container | Small, circular dot | Visible as red dot by default, no text |
Large Badge


- Displays number or text for explicit notifications
- Suitable for counts or status labels
Example with Number
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="@+id/bottom_navigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
app:menu="@menu/bottom_nav_menu"/>
val badgeDrawable = BadgeDrawable.create(context)
badgeDrawable.number = 99
badgeDrawable.maxNumber = 999
val anchorView = bottomNavigation.findViewById<View>(R.id.nav_item)
BadgeUtils.attachBadgeDrawable(badgeDrawable, anchorView)
badgeDrawable.setContentDescriptionQuantityStringsResource(R.plurals.badge_count)
Example with Text
val badgeDrawable = BadgeDrawable.create(context)
badgeDrawable.badgeText = "999+"
badgeDrawable.maxCharacterCount = 4
val anchorView = bottomNavigation.findViewById<View>(R.id.nav_item)
BadgeUtils.attachBadgeDrawable(badgeDrawable, anchorView)
badgeDrawable.setContentDescriptionForText("Over 999 notifications")
Large Badge Anatomy

Component | Description | Behavior |
---|---|---|
Container | Rounded rectangle with text | Red background, white text by default |
Label | Numeric or text, capped by limits | Displays number or text, centered |
Attributes and Usage
Element | Attribute | Related Method(s) | Default Value | Usage Description | Variant |
---|---|---|---|---|---|
Container | app:backgroundColor |
setBackgroundColor , getBackgroundColor |
@android:color/red |
Sets badge background color | All |
Container | app:badgeWidth |
setBadgeWidth , getBadgeWidth |
Dynamic | Sets width for small badge | Small |
Container | app:badgeWithTextWidth |
setBadgeWithTextWidth , getBadgeWithTextWidth |
Dynamic | Sets width for large badge | Large |
Container | app:badgeShapeAppearance |
setShapeAppearanceModel , getShapeAppearanceModel |
Circular (Small), Rounded (Large) | Sets badge shape | All |
Label | app:badgeText |
setBadgeText , getBadgeText |
null |
Sets text label | Large |
Label | app:number |
setNumber , getNumber |
0 | Sets numeric count | Large |
Label | app:badgeTextColor |
setTextColor , getTextColor |
@android:color/white |
Sets text color | Large |
Position | app:badgeGravity |
setBadgeGravity , getBadgeGravity |
TOP_END |
Sets alignment (TOP_END, TOP_START) | All |
Position | app:horizontalOffset |
setHorizontalOffset , getHorizontalOffset |
0 | Sets horizontal offset from anchor | All |
Theming BadgeDrawable

- Limited theming via programmatic color and shape adjustments
- Theme attributes not fully supported
Example
val badgeDrawable = BadgeDrawable.create(context)
badgeDrawable.backgroundColor = ContextCompat.getColor(context, R.color.shrine_pink_900)
badgeDrawable.badgeTextColor = ContextCompat.getColor(context, R.color.white)
Material Design Documentation
- Adheres to Material Design guidelines for Badges
- Covers design, behavior, theming specifications
- Includes structure, accessibility, limited theming
- Refer to Material Design documentation for full details
FAQ
What is a Material 3 BadgeDrawable?
- A dynamic indicator for notifications or counts on UI components
How many badge types are there?
- Three types: Icon-only, With Number, With Text
When to use an Icon-only Badge?
- Use for subtle alerts without specific counts
How to make badges accessible?
- Use
setContentDescriptionForText
for screen readers
Can I customize badge appearance?
- Yes, programmatically adjust color and shape
How to add the Material 3 library?
- Include Material Components for Android library
Are there updates for the latest standards?
- Reflects latest Material 3 standards for BadgeDrawable
Tags:
MDC Android