SecondaryTabRow

Secondary tabs are used within a content area to further separate related content and establish hierarchy. Fixed tabs display all tabs in a set simultaneously. To navigate between fixed tabs, tap an individual tab, or swipe left or right in the content area.

A TabRow contains a row of [Tab]s, and displays an indicator underneath the currently selected tab. A Fixed TabRow places its tabs evenly spaced along the entire row, with each tab taking up an equal amount of space. See [SecondaryScrollableTabRow] for a tab row that does not enforce equal size, and allows scrolling to tabs that do not fit on screen.

Installation

This component is available for Jetpack Compose (Android) and Compose Desktop

dependencies {
   implementation("androidx.compose.material3:material3:1.3.0-alpha06")
}

Overloads

@Composable
@ExperimentalMaterial3Api
fun SecondaryTabRow(
    selectedTabIndex: Int,
    modifier: Modifier = Modifier,
    containerColor: Color = TabRowDefaults.secondaryContainerColor,
    contentColor: Color = TabRowDefaults.secondaryContentColor,
    indicator: @Composable TabIndicatorScope.() -> Unit = @Composable {
        TabRowDefaults.SecondaryIndicator(
            Modifier.tabIndicatorOffset(selectedTabIndex, matchContentSize = false)
        )
    },
    divider: @Composable () -> Unit = @Composable {
        HorizontalDivider()
    },
    tabs: @Composable () -> Unit
)

Parameters

namedescription
selectedTabIndexthe index of the currently selected tab
modifierthe [Modifier] to be applied to this tab row
containerColorthe color used for the background of this tab row. Use [Color.Transparent] to have no color.
contentColorthe preferred color for content inside this tab row. Defaults to either the matching content color for [containerColor], or to the current [LocalContentColor] if [containerColor] is not a color from the theme.
indicatorthe indicator that represents which tab is currently selected. By default this will be a [TabRowDefaults.SecondaryIndicator], using a [TabRowDefaults.tabIndicatorOffset] modifier to animate its position. Note that this indicator will be forced to fill up the entire tab row, so you should use [TabRowDefaults.tabIndicatorOffset] or similar to animate the actual drawn indicator inside this space, and provide an offset from the start.
dividerthe divider displayed at the bottom of the tab row. This provides a layer of separation between the tab row and the content displayed underneath.
tabsthe tabs inside this tab row. Typically this will be multiple [Tab]s. Each element inside this lambda will be measured and placed evenly across the row, each taking up equal space.

Code Example

SecondaryTextTabs

@Composable
fun SecondaryTextTabs() {
    var state by remember { mutableStateOf(0) }
    val titles = listOf("Tab 1", "Tab 2", "Tab 3 with lots of text")
    Column {
        SecondaryTabRow(selectedTabIndex = state) {
            titles.forEachIndexed { index, title ->
                Tab(
                    selected = state == index,
                    onClick = { state = index },
                    text = { Text(text = title, maxLines = 2, overflow = TextOverflow.Ellipsis) }
                )
            }
        }
        Text(
            modifier = Modifier.align(Alignment.CenterHorizontally),
            text = "Secondary tab ${state + 1} selected",
            style = MaterialTheme.typography.bodyLarge
        )
    }
}
Previous ComponentSecondaryScrollableTabRow
Next ComponentSingleChoiceSegmentedButtonRow