Search code examples
androidandroid-jetpack-composematerial-designmaterial-components-androidandroid-jetpack-compose-material3

How to add curved tab when using TabRow and Tab with Compose and Material 3?


I am trying to add the TabRow and Tab from Material 3 library on an Android Jetpack Compose application. The tab indicators are always in plain stroke and doesn't reflect the actual curved indicator as shown in the M3 website.

From M3 Compose Code From M3 Website
2 Tabs inside a TabRow Note the primary example
TabRow(
    selectedTabIndex = periodIndex,
) {
    periodLabels.forEachIndexed { index, title ->
        Tab(
            selected = periodIndex == index,
            onClick = { periodIndex = index },
            text = { Text(
                text = title,
                maxLines = 1,
                overflow = TextOverflow.Ellipsis,
                color = MaterialTheme.colorScheme.onSurface
            ) }
        )
    }
}

How to get the version of Tab that resembles in the official design of M3?


Solution

  • You can provide a custom indicator for the active indicator.

    enter image description here

    Code

    @Composable
    fun TabRowDemo() {
        var periodIndex by remember {
            mutableStateOf(0)
        }
        val periodLabels = listOf(
            "Upcoming",
            "Past",
        )
    
        BoxWithConstraints {
            TabRow(
                selectedTabIndex = periodIndex,
                indicator = { tabPositions ->
                    if (periodIndex < tabPositions.size) {
                        TabRowDefaults.PrimaryIndicator(
                            modifier = Modifier
                                .tabIndicatorOffset(tabPositions[periodIndex]),
                            width = maxWidth / periodLabels.size,
                            shape = RoundedCornerShape(
                                topStart = 3.dp,
                                topEnd = 3.dp,
                                bottomEnd = 0.dp,
                                bottomStart = 0.dp,
                            ),
                        )
                    }
                },
            ) {
                periodLabels.forEachIndexed { index, title ->
                    Tab(
                        selected = periodIndex == index,
                        onClick = {
                            periodIndex = index
                        },
                        text = {
                            Text(
                                text = title,
                                maxLines = 1,
                                overflow = TextOverflow.Ellipsis,
                                color = MaterialTheme.colorScheme.onSurface,
                            )
                        }
                    )
                }
            }
        }
    }