0

I want to make a ScrollableTabRow that goes past the width of the screen to make it clearer that there are more tabs to scroll through. It should look something like this:

When scrolled all the way to the left: When scrolled all the way to the left

When scrolled somewhere in the middle: When scrolled somewhere in the middle

When scrolled all the way to the right: When scrolled all the way to the right

However, I cannot achieve it using the Material component ScrollableTabRow because the ScrollableTabRow is filling the remaining width of the screen, instead of fully wrapping its content.

When scrolled all the way to the left: When scrolled all the way to the left

When scrolled all the way to the right: When scrolled all the way to the right

Here is my code using the ScrollableTabRow composable:

Note: 1.unit is equal to 4.dp

Row {
    HorizontalSpacer(width = 4.unit)
    ScrollableTabRow(
        modifier = Modifier.clip(CircleShape).wrapContentSize(),
        selectedTabIndex = pagerState.currentPage,
        indicator = { tabPositions ->
            SpecsheetTabIndicator(tabPositions = tabPositions, pagerState = pagerState)
        },
        edgePadding = 0.dp,
        divider = {},
        containerColor = MaterialTheme.colorScheme.primaryContainer,
    ) {
        for ((index, tab) in tabs.withIndex()) {
            val textColor by animateColorAsState(
                targetValue = when (pagerState.currentPage) {
                    index -> MaterialTheme.colorScheme.onPrimary
                    else -> MaterialTheme.colorScheme.onPrimaryContainer
                },
            )

            Tab(
                modifier = Modifier
                    .zIndex(6f)
                    .clip(CircleShape),
                selected = pagerState.currentPage == index,
                onClick = {
                    coroutineScope.launch {
                        pagerState.animateScrollToPage(index)
                    }
                },
                text = {
                    Text(
                        text = tab.text(),
                        color = textColor,
                    )
                },
            )
        }
    }
    HorizontalSpacer(width = 4.unit)
}

Also, as you can see in my code above, the Row is not really scrolling because I am not sure how to implement nested scrolling. Adding a horizontalScroll modifier to the Row makes the app crash because of the unhandled nested scrolling.

I have achieved the behavior I wanted as demonstrated in the first three images using regular rows:

Row(
    modifier = Modifier.horizontalScroll(scrollState),
) {
    HorizontalSpacer(width = 4.unit)
    Row(
        modifier = Modifier
            .clip(CircleShape)
            .background(MaterialTheme.colorScheme.primaryContainer)
    ) {
        for ((index, tab) in tabs.withIndex()) {
            val containerColor by animateColorAsState(
                targetValue = when (pagerState.currentPage) {
                    index -> MaterialTheme.colorScheme.primary
                    else -> Color.Transparent
                },
            )
            val textColor by animateColorAsState(
                targetValue = when (pagerState.currentPage) {
                    index -> MaterialTheme.colorScheme.onPrimary
                    else -> MaterialTheme.colorScheme.onPrimaryContainer
                },
            )
            Surface(
                modifier = Modifier.clip(CircleShape),
                color = containerColor,
            ) {
                Tab(
                    modifier = Modifier
                        .zIndex(6f)
                        .clip(CircleShape)
                        .defaultMinSize(minWidth = 24.unit),
                    selected = pagerState.currentPage == index,
                    onClick = {
                        coroutineScope.launch {
                            pagerState.animateScrollToPage(index)
                        }
                    },
                    text = {
                        Text(
                            text = tab.text(),
                            color = textColor,
                        )
                    },
                )
            }
        }
    }
    HorizontalSpacer(width = 4.unit)
}

However, I don't know how to reimplement a lot of the behavior that are built into the ScrollableTabRow like the proper rendering of the indicator and the proper scrolling of the tab row to the selected tab when the selected tab is not visible. Can anyone help me make this work for me?

hamthenormal
  • 856
  • 8
  • 21

1 Answers1

0

did you try setting edgePadding on the ScrollableTabRow?