'Android Jetpack Compose white TabRow
I am trying to get Tabs working with a TabRow on Android with compose. What I'd like is the TabRow to have a white background. The default color seems to be this purple(ish) as shown in the documentation (https://developer.android.com/reference/kotlin/androidx/compose/material/package-summary).
When I set backgroundColor to White the Tabs are grey for some reason.
How would you achieve white Tabs in Compose?
Thanks!
Solution 1:[1]
EDIT: Google have now fixed this issue: https://issuetracker.google.com/issues/197254738. Hopefully it will find its way into a JC release soon!
Question's a couple of months old, but recently encountered this issue so others might find these solutions useful:
Solution 0 (quickest)
Don't have a divider. For example:
TabRow(
selectedTabIndex = ...,
modifier = Modifier.height(100.dp).fillMaxWidth(),
divider = {}
) { /* content here */ }
Solution 1
Since the TabRow is just a container, don't specify a height
in its modifier. If you want it to have a custom height, instead make sure that each of the Tabs have their heights specified explicitly. For example:
var selectedTabIndex by remember { mutableStateOf(0) }
TabRow(
selectedTabIndex = selectedTabIndex,
modifier = Modifier.fillMaxWidth(), // Don't specify the TabRow's height!
backgroundColor = Colors.White
) {
listOf("Hello", "World").forEachIndexed { i, text ->
Tab(
selected = selectedTabIndex == i,
onClick = { selectedTabIndex = i },
modifier = Modifier.height(50.dp), // Specify the Tab's height instead
text = { Text(text) }
)
}
}
Solution 2
Force the divider to only draw at the bottom of the layout. This is consistent with the default indicator implementation.
TabRow(
selectedTabIndex = ...,
modifier = Modifier.height(100.dp).fillMaxWidth(),
backgroundColor = Colors.White,
divider = { TabRowDefaults.Divider(Modifier.wrapContentSize(Alignment.BottomStart)) },
) { /* content here */ }
Explanation
From the source code here and here, the default divider has height 1dp. However, the OP is seeing a grey background because the divider is drawing over the whole TabRow!
When you specify a height
constraint on a TabRow
, the constraint gets passed through to the divider (source code here). The divider therefore takes up the entire height of the TabRow – in OP's case, the divider is a transparent grey colour, so it makes the TabRow look grey. The above solutions have a few different ways to solve the problem:
- Removing the divider removes the issue!
- TabRows wrap their tabs, so an alternative solution is to give the TabRow height by specifying the tabs' heights rather than the TabRow's.
- This forces the divider to ignore the TabRow's height constraint, and instead draw itself at its correct height at the BottomStart position in the TabRow.
Solution 2:[2]
You can set color using backgroundColor: Color = MaterialTheme.colors.primarySurface,
.
Sample code below:
@Composable
fun TabRow(
selectedTabIndex: Int,
modifier: Modifier = Modifier,
backgroundColor: Color = MaterialTheme.colors.primarySurface,
contentColor: Color = contentColorFor(backgroundColor),
indicator: (List<TabPosition>) -> Unit = @Composable { tabPositions ->
TabRowDefaults.Indicator(
Modifier.tabIndicatorOffset(tabPositions[selectedTabIndex])
)
},
divider: () -> Unit = @Composable {
TabRowDefaults.Divider()
},
tabs: () -> Unit
): @Composable Unit
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | dumbfingers |
Solution 2 | minchaej |