TopAppBar not adjusting height automatically in Compose and TabRow not working

8.5k Views Asked by At

Basically, I have two composable funcs which create a TopAppBar and add a tab layout contained in the app bar :

@Composable
fun ZCryptAppBar(
    modifier: Modifier = Modifier,
    title: @Composable RowScope.() -> Unit
) {
    Column(Modifier.fillMaxWidth()) {
        TopAppBar(
            title = {
                Column {
                    Row { title() }
                    Row {
                        TabLayout()
                    }
                }
            },
            modifier = modifier,
            backgroundColor = MaterialTheme.colors.primary,
            contentColor = Color.White
        )
    }
}

@Composable
fun TabLayout() {
    var selectedTab by remember {
        mutableStateOf(0)
    }
    TabRow(
        modifier = Modifier.fillMaxWidth(),
        selectedTabIndex = selectedTab,
        backgroundColor = MaterialTheme.colors.primary,
        tabs = {
            Tab(
                selected = selectedTab == 0,
                onClick = { selectedTab = 0 },
                text = { Text(stringResource(R.string.encrypt)) },
                icon = {
                    Image(
                        painterResource(id = R.drawable.ic_padlock_black),
                        stringResource(R.string.descr_icon_padlock)
                    )
                }
            )
            Tab(
                selected = selectedTab == 0,
                onClick = { selectedTab = 0 },
                text = { Text(stringResource(R.string.decrypt)) },
                icon = {
                    Image(
                        painterResource(id = R.drawable.ic_padunlock_black),
                        stringResource(R.string.descr_icon_padunlock)
                    )
                }
            )
        }
    )
}

But I am having two problems here : firstly, when I click on a tab, nothing happens and app stays in the same tab.

Secondly, the TopAppBar seems to not automatically adjust its height since the tab name and icon are all cropped :

2

There are 2 best solutions below

4
On BEST ANSWER

The TopAppBar implements the Material design specs and has a fixed height of 56.dp.

You can use:

Column(Modifier.fillMaxWidth()) {
    TopAppBar(
        title = {
            Column() {
                Row { Text("Title") }
            }
        },
        backgroundColor = MaterialTheme.colors.primary,
        contentColor = Color.White
    )
    TabLayout()
}

Then in your TabLayout use:

       Tab(
            selected = selectedTab == 0,
            onClick = { selectedTab = 0 },
            //.....
        )
        Tab(
            selected = selectedTab == 1,
            onClick = { selectedTab = 1 },
            //.....
        )

enter image description here

6
On
@Composable
fun ZCryptAppBar(
    modifier: Modifier = Modifier,
    title: @Composable RowScope.() -> Unit
) {
    Column(Modifier.fillMaxWidth()) {
        TopAppBar(
            content = {
                Column {
                    Row { title() }
                    Row {
                        TabLayout()
                    }
                }
            },
            modifier = modifier,
            backgroundColor = MaterialTheme.colors.primary,
            contentColor = Color.White
        )
    }
}

@Composable
fun TabLayout() {
    var selectedTab by remember {
        mutableStateOf(0)
    }
    TabRow(
        modifier = Modifier.fillMaxWidth(),
        selectedTabIndex = selectedTab,
        backgroundColor = MaterialTheme.colors.primary,
        tabs = {
            Tab(
                selected = selectedTab == 0,
                onClick = { selectedTab = 0 },
                text = { Text(stringResource(R.string.encrypt)) },
                icon = {
                    Image(
                        painterResource(id = R.drawable.ic_padlock_black),
                        stringResource(R.string.descr_icon_padlock)
                    )
                }
            )
            Tab(
                selected = selectedTab == 1,
                onClick = { selectedTab = 1 },
                text = { Text(stringResource(R.string.decrypt)) },
                icon = {
                    Image(
                        painterResource(id = R.drawable.ic_padunlock_black),
                        stringResource(R.string.descr_icon_padunlock)
                    )
                }
            )
        }
    )
}

When copying and pasting, it is common to forget to change values. Funny it happens so often I myself do it many times. Try it out

Oh by the way, here you were using the wrong variant of the ``TopAppBar``` The reason for the clipping was probably the fact that you were stuffing everything in the title of the bar. Using 'content' instead should fix that. If it doesn't, try Modifier.wrapContentSize()

Tabs were not changing since you applied the same logic in both the tabs.