How to make scrollable Tabrow fill max width in landscape mode in Jetpack Compose?

35 views Asked by At

When changing screen orientation to landscape mode, the Scrollable Tabrow only occupies half of the screen, as in this image. I want to make it fill max width of the screen.

As of the following code, I've made the scrollable tabrow fill max width.

Image

ScrollableTabRow(
        selectedTabIndex = pagerState.currentPage,
        edgePadding = 0.dp,
        divider = {
            Spacer(modifier = Modifier.height(1.dp))
        },
        indicator = { tabPositions ->
            SecondaryIndicator(
                modifier = Modifier.customTabIndicatorOffset(
                    currentTabPosition = tabPositions[pagerState.currentPage],
                    tabWidth = tabWidths[pagerState.currentPage]
                ),
                color = MaterialTheme.colorScheme.primary
            )
        },


        modifier = Modifier
            .fillMaxWidth()
            .background(MaterialTheme.customColorsPalette.mainAppBar)
            .wrapContentHeight()
    ) {
        tabData.forEachIndexed { index, title ->
            Tab(
                modifier = Modifier.background(MaterialTheme.customColorsPalette.mainAppBar),
                selected = pagerState.currentPage == index, onClick = {
                scope.launch {
                    pagerState.animateScrollToPage(index)
                }
            },
                text = {
                    Text(
                        text = title,
                        onTextLayout = { textLayoutResult ->
                            tabWidths[index] =
                                with(density) { textLayoutResult.size.width.toDp() }
                        }
                    )
                }
            )
        }
    }
1

There are 1 answers

0
Miroslav Hýbler On BEST ANSWER

For making it full width you have to use TabRow which is not scrollable and tabs are created with equal weight making it fill the width. However you have to be sure that in landscape all items will fit into TabRow.

I updated your code:

  • for portrait ScrollableTabRow is used where tabs occupying just that space they need and row is scrollable
  • for landscape TabRow is used where items fills maximum width but they are not scrollable. It's almost the same, only difference is that TabRowdoes not have edgePadding property.
@Composable
fun CustomTabsRow() {
    val configuration = LocalConfiguration.current
    val tabData = remember {
        listOf("Events", "Details", "Lineups", "Stats", "Endings")
    }
    val scope = rememberCoroutineScope()
    val pagerState = rememberPagerState {
        tabData.size
    }

    if (configuration.orientation == Configuration.ORIENTATION_LANDSCAPE) {
        TabRow(
            selectedTabIndex = pagerState.currentPage,
            divider = {
                Spacer(modifier = Modifier.height(1.dp))
            },
            indicator = { tabPositions ->
                SecondaryIndicator(
                    modifier = Modifier.customTabIndicatorOffset(
                        currentTabPosition = tabPositions[pagerState.currentPage],
                        tabWidth = tabWidths[pagerState.currentPage]
                    ),
                    color = MaterialTheme.colorScheme.primary
                )
            },
            modifier = Modifier
                .fillMaxWidth()
                .background(MaterialTheme.customColorsPalette.mainAppBar)
                .wrapContentHeight()
        ) {
            tabData.forEachIndexed { index, title ->
                Tab(
                    modifier = Modifier.background(MaterialTheme.customColorsPalette.mainAppBar),
                    selected = pagerState.currentPage == index, onClick = {
                        scope.launch {
                            pagerState.animateScrollToPage(index)
                        }
                    },
                    text = {
                        Text(
                            text = title,
                            onTextLayout = { textLayoutResult ->
                                tabWidths[index] =
                                    with(density) { textLayoutResult.size.width.toDp() }
                            }
                        )
                    }
                )
            }
        }
    } else {
        ScrollableTabRow(
            selectedTabIndex = pagerState.currentPage,
            edgePadding = 0.dp,
            divider = {
                Spacer(modifier = Modifier.height(1.dp))
            },
            indicator = { tabPositions ->
                SecondaryIndicator(
                    modifier = Modifier.customTabIndicatorOffset(
                        currentTabPosition = tabPositions[pagerState.currentPage],
                        tabWidth = tabWidths[pagerState.currentPage]
                    ),
                    color = MaterialTheme.colorScheme.primary
                )
            },
            modifier = Modifier
                .fillMaxWidth()
                .background(MaterialTheme.customColorsPalette.mainAppBar)
                .wrapContentHeight()
        ) {
            tabData.forEachIndexed { index, title ->
                Tab(
                    modifier = Modifier.background(MaterialTheme.customColorsPalette.mainAppBar),
                    selected = pagerState.currentPage == index, onClick = {
                        scope.launch {
                            pagerState.animateScrollToPage(index)
                        }
                    },
                    text = {
                        Text(
                            text = title,
                            onTextLayout = { textLayoutResult ->
                                tabWidths[index] =
                                    with(density) { textLayoutResult.size.width.toDp() }
                            }
                        )
                    }
                )
            }
        }
    }
}