# Tabs [Tabs](https://m3.material.io/components/tabs/overview) organize content across different screens, data sets, and other interactions. There are two variants of tabs. ![Types of tabs](assets/tabs/tabs-types.png) 1. Primary tabs 2. Secondary tabs **Primary tabs** are placed at the top of the content pane under an app bar. They display the main content destinations. **Secondary tabs** are used within a content area to further separate related content and establish hierarchy. **Note:** Images use various dynamic color schemes. ## Design & API documentation * [Material 3 (M3) spec](https://m3.material.io/components/tabs/overview) * [API reference](https://developer.android.com/reference/com/google/android/material/tabs/package-summary) ## Anatomy #### Primary tabs ![Primary tabs anatomy](assets/tabs/primary-tabs-anatomy.png) 1. Container 2. Badge (optional) 3. Icon (optional) 4. Label 5. Divider 6. Active indicator #### Secondary tabs ![Secondary tabs anatomy](assets/tabs/secondary-tabs-anatomy.png) 1. Container 2. Badge (optional) 3. Label 4. Divider 5. Active indicator More details on anatomy items in the [component guidelines](https://m3.material.io/components/tabs/guidelines#9b89bb22-e4b2-4de2-9844-14ebf7524760). ## Key properties ### Container attributes Element | Attribute | Related method(s) | Default value ------------- | -------------------- | ---------------------------------- | ------------- **Color** | `android:background` | `setBackground`
`getBackground` | `?attr/colorOnSurfaceVariant` **Elevation** | `android:elevation` | `setElevation` | `0dp` **Height** | N/A | N/A | `48dp` (inline text) or `72dp` (non-inline text and icon) **Tab mode** | `tabMode` | `setTabMode`
`getTabMode` | `fixed` ### Tab item icon attributes Element | Attribute | Related method(s) | Default value --------- | -------------- | ---------------------------------------------------------------- | ------------- **Icon** | `android:icon` | `setIcon`
`getIcon` | `null` **Color** | `tabIconTint` | `setTabIconTint`
`setTabIconTintResource`
`getTabIconTint` | `colorOnSurfaceVariant` and `colorPrimary` (activated) (see all [states](https://github.com/material-components/material-components-android/tree/master/lib/java/com/google/android/material/tabs/res/color/m3_tabs_icon_color.xml)) ### Tab item text label attributes Element | Attribute | Related method(s) | Default value ------------------------- | --------------------------- | --------------------------------------------------------------- | ------------- **Text** | `android:text` | `setText`
`getText` | `null` **Color** | `tabTextColor` | `setTabTextColors`
`getTabTextColors` | `colorOnSurfaceVariant` and `colorPrimary` (activated) (see all [states](https://github.com/material-components/material-components-android/tree/master/lib/java/com/google/android/material/tabs/res/color/m3_tabs_icon_color.xml)) **Typography** | `tabTextAppearance` | N/A | `?attr/textAppearanceTitleSmall` **Active tab typography** | `tabSelectedTextAppearance` | N/A | None; will use `tabTextAppearance` instead **Inline label** | `tabInlineLabel` | `setInlineLabel`
`setInlineLabelResource`
`isInlineLabel` | `false` **Note:** When using `tabSelectedTextAppearance`, you must have matching text attributes in `tabTextAppearance` to avoid unintended behavior. ### Tab item container attributes Element | Attribute | Related method(s) | Default value -------------------- | --------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------- | ------------- **Ripple color** | `tabRippleColor` | `setTabRippleColor`
`setTabRippleColorResource`
`getTabRippleColor` | `colorOnSurfaceVariant` at 16% opacity and `colorPrimary` at 16% opacity (activated) (see all [states](https://github.com/material-components/material-components-android/tree/master/lib/java/com/google/android/material/tabs/res/color/m3_tabs_ripple_color.xml)) **Unbounded ripple** | `tabUnboundedRipple` | `setUnboundedRipple`
`setUnboundedRippleResource`
`hasUnboundedRipple` | `false` **Gravity** | `tabGravity` | `setTabGravity`
`getTabGravity` | `fill` **Min width** | `tabMinWidth` | N/A | `72dp` (scrollable) or `wrap_content` **Max width** | `tabMaxWidth` | N/A | `264dp` **Padding** | `tabPaddingStart`
`tabPaddingEnd`
`tabPaddingTop`
`tabPaddingBottom`
`tabPadding` | N/A | `12dp`
`12dp`
`0dp`
`0dp`
`0dp` ### Tab indicator attributes Element | Attribute | Related method(s) | Default value ---------------------- | ------------------------------- | ---------------------------------------------------------------- | ------------- **Color** | `tabIndicatorColor` | `setSelectedTabIndicatorColor` | `colorPrimary` **Drawable** | `tabIndicator` | `setSelectedTabIndicator`
`getSelectedTabIndicator` | [`m3_tabs_rounded_line_indicator`](https://github.com/material-components/material-components-android/tree/master/lib/java/com/google/android/material/tabs/res/drawable/m3_tabs_rounded_line_indicator.xml) **Height** | `tabIndicatorHeight` | `setSelectedTabIndicatorHeight` | `2dp` **Full width** | `tabIndicatorFullWidth` | `setTabIndicatorFullWidth`
`isTabIndicatorFullWidth` | `false` **Animation mode** | `tabIndicatorAnimationMode` | `setTabIndicatorAnimationMode`
`getTabIndicatorAnimationMode` | `elastic` **Gravity** | `tabIndicatorGravity` | `setSelectedTabIndicatorGravity`
`getTabIndicatorGravity` | `bottom` **Animation duration** | `tabIndicatorAnimationDuration` | N/A | `250` ### Styles Element | Style | Theme attribute --------------------------------- | -------------------------------------- | --------------- **Default style** | `Widget.Material3.TabLayout` | `?attr/tabStyle` **Style for elevatable surfaces** | `Widget.Material3.TabLayout.OnSurface` | N/A **Primary secondary color style** | `Widget.Material3.TabLayout.Secondary` | `?attr/tabSecondaryStyle` For the full list, see [styles](https://github.com/material-components/material-components-android/tree/master/lib/java/com/google/android/material/tabs/res/values/styles.xml) and [attrs](https://github.com/material-components/material-components-android/tree/master/lib/java/com/google/android/material/tabs/res/values/attrs.xml). ## Code implementation Before you can use Material tabs, you need to add a dependency to the Material components for Android library. For more information, go to the [Getting started](https://github.com/material-components/material-components-android/tree/master/docs/getting-started.md) page. ### Adding tabs ![Three fixed tabs with one tab selected.](assets/tabs/tabs-basic.png) A [`TabLayout`](https://github.com/material-components/material-components-android/tree/master/lib/java/com/google/android/material/tabs/TabLayout.java) can be added to a layout: ```xml ... ``` [`TabItem`](https://github.com/material-components/material-components-android/tree/master/lib/java/com/google/android/material/tabs/TabItem.java)s can then be added as children of the `TabLayout` and adjusted as needed: ```xml ... ``` Observe changes to tab selections: ```kt tabLayout.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener { override fun onTabSelected(tab: TabLayout.Tab?) { // Handle tab select } override fun onTabReselected(tab: TabLayout.Tab?) { // Handle tab reselect } override fun onTabUnselected(tab: TabLayout.Tab?) { // Handle tab unselect } }) ``` ### Making tabs accessible The Android tab components support screen reader descriptions for tabs and badges. While optional, we strongly encourage their use. #### Content description Adding a content descriptions to the entire `TabLayout` can be done in XML with the `android:contentDescription` attribute or programmatically: ```kt tabLayout.contentDescription = contentDescription ``` Content descriptions can also be added to individual tabs: ```kt val tab = tabLayout.getTabAt(index) tab?.contentDescription = contentDescription ``` `BadgeDrawable` also has a number of content description setters for different badge states: ```kt val badge = tab.getOrCreateBadge() // For badges with a number badge.setContentDescriptionNumberless(contentDescription) badge.setContentDescriptionQuantityStringsResource(R.string.content_description) badge.setContentDescriptionExceedsMaxBadgeNumberStringResource(R.string.content_description) // For badges with a text badge.setContentDescriptionForText(contentDescription) ``` ### Using tabs with ViewPager A `TabLayout` can be set up with a [`ViewPager`](https://developer.android.com/reference/androidx/viewpager/widget/ViewPager) in order to: * Dynamically create `TabItem`s based on the number of pages, their titles, etc. * Synchronize the selected tab and tab indicator position with page swipes First, your [`PagerAdapter`](https://developer.android.com/reference/androidx/viewpager/widget/PagerAdapter) (or subclass) needs to override the `getPageTitle` function in order to set the tab text label: ```kt class Adapter : PagerAdapter() { ... override fun getPageTitle(position: Int): CharSequence? { // Return tab text label for position } } ``` After the adapter has been set on the `ViewPager`, synchronize the `TabLayout`: ```kt tabLayout.setupWithViewPager(viewPager) ``` Further customization of the dynamically-created `TabItem`s (such as setting icons) needs to be done separately: ```kt val tab = tabLayout.getTabAt(index) tab?.icon = drawable ``` ### Using tabs with ViewPager2 Setting up a `TabLayout` with a [`ViewPager2`](https://developer.android.com/reference/androidx/viewpager2/widget/ViewPager2) relies on the same concepts as doing so with a `ViewPager`, but the implementation is different. Everything is handled by the [`TabLayoutMediator`](https://github.com/material-components/material-components-android/tree/master/lib/java/com/google/android/material/tabs/TabLayoutMediator.java) class: ```kt TabLayoutMediator(tabLayout, viewPager2) { tab, position -> when (position) { 0 -> { tab.text = textLabel1 tab.icon = drawable1 } 1 -> { tab.text = textLabel2 tab.icon = drawable2 } ... } }.attach() ``` ### Adding badges to tabs ![Example of 3 fixed tabs with badges: a red badge with "1", a red badge with "88", and a red badge with "999".](assets/tabs/tabs-badged.png) Tabs support badging with the [`BadgeDrawable`](https://github.com/material-components/material-components-android/tree/master/lib/java/com/google/android/material/badge/BadgeDrawable.java) class: ```kt // Get badge from tab (or create one if none exists) val badge = tab.getOrCreateBadge() // Customize badge badge.number = number // Remove badge from tab tab.removeBadge() ``` ### Adding fixed tabs Fixed tabs display all tabs on one screen, with each tab at a fixed width. The width of each tab is determined by dividing the number of tabs by the screen width. They don’t scroll to reveal more tabs; the visible tab set represents the only tabs available. #### Fixed tabs example The following example shows a row of fixed tabs. ![Example of 3 fixed tabs.](assets/tabs/tabs-fixed.png) In the layout: ```xml ``` ### Adding scrollable tabs Scrollable tabs are displayed without fixed widths. They are scrollable, such that some tabs will remain off-screen until scrolled. #### Scrollable tabs example The following example shows a row of scrollable tabs. ![Example of 6 scrollable tabs, with the 6th partially cut off by screensize.](assets/tabs/tabs-scrollable.png) In the layout: ```xml ... ``` ## Customizing tabs ### Theming tabs Tabs support the customization of color and typography. #### Tabs theming example API and source code: * `TabLayout` * [Class definition](https://developer.android.com/reference/com/google/android/material/tabs/TabLayout) * [Class source](https://github.com/material-components/material-components-android/tree/master/lib/java/com/google/android/material/tabs/TabLayout.java) * `TabItem` * [Class definition](https://developer.android.com/reference/com/google/android/material/tabs/TabItem) * [Class source](https://github.com/material-components/material-components-android/tree/master/lib/java/com/google/android/material/tabs/TabItem.java) The following example shows a row of scrollable tabs with Material theming. ![Example of 4 scrollable tabs with light pink background. The selected text is dark pink, the unselected text is grey.](assets/tabs/tabs-theming.png) ##### Implementing tabs theming Use theme attributes and styles in `res/values/styles.xml` which applies to all tabs and affects other components: ```xml ``` Use default style theme attributes, styles and theme overlays, which apply to all tabs but do not affect other components: ```xml ``` Use the style in the layout, which affects only these tabs: ```xml ```