Left aligned custom tabs with Jetpack Compose

Viewed 902

I need to make tabs with Jetpack Compose, looking like horizontal buttons. Tabs should be left aligned, and not centered. Just like in the image. Also selected tab shouldn't show underline.

enter image description here

3 Answers

Jetpack compose has Scaffold for such case, something like this should work for you

enum class Tab {
    Day,
    Week,
    Month,
}

@Composable
fun TestView(
) {
    var selectedTab by remember { mutableStateOf(Tab.Day) }
    Scaffold(topBar = {
        Row(Modifier.padding(5.dp)) {
            Tab.values().forEach { tab ->
                BottomBarButton(
                    tab.name,
                    selected = selectedTab == tab,
                    onSelect = {
                        selectedTab = tab
                    },
                )
            }
        }
    }) {
        when (selectedTab) {
            Tab.Day -> Text("$selectedTab content")
            Tab.Week -> Text("$selectedTab content")
            Tab.Month -> Text("$selectedTab content")
        }
    }
}

@Composable
fun BottomBarButton(
    text: String,
    selected: Boolean,
    onSelect: () -> Unit
) {
    Text(
        text,
        modifier = Modifier
            .background(
                if (selected)
                    Color.Green
                else
                    Color.Transparent
            )
            .clickable(onClick = onSelect)
            .padding(10.dp)
    )
}

If you need bottom bar, just replace topBar = { with bottomBar = {

See more about Scaffold

How about this one?

ScrollableTabRow(
            selectedTabIndex = pagerState.currentPage,
            backgroundColor = colorResource(id = R.color.white),
            divider = { TabRowDefaults.Divider(color = colorResource(id = R.color.transparent)) },
            edgePadding = 0.dp
        ) {
            //draw your tab
        }

Try this out

import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.gestures.Orientation
import androidx.compose.foundation.gestures.scrollable
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp

@Composable
fun RecentTabs(tabs: List<CustomTabs>, onSelectedTab: (CustomTabs) -> Unit) {
    var selectedTab by remember { mutableStateOf("") }
    @Composable
    fun RecentTabItem(text: String, selectedColor: Color = Color.Green, onSelect: () -> Unit) {
        val selected = text == selectedTab
        Text(
            text,
            modifier = Modifier
                .clip(CircleShape)
                .background(
                    if (selected)
                        selectedColor
                    else
                        Color.Transparent
                )
                .clickable(
                    onClick = {
                        selectedTab = text
                        onSelect.invoke()
                    }
                )
                .padding(vertical = 8.dp, horizontal = 18.dp)
        )
    }
    Row(
        Modifier
            .scrollable(rememberScrollState(), orientation = Orientation.Horizontal)
            .padding(horizontal = 5.dp, vertical = 8.dp)) {
        tabs.forEach {
            RecentTabItem(text = it.name, selectedColor = it.color.toColor(Color.Magenta)) { onSelectedTab.invoke(it) }
            Spacer(modifier = Modifier.width(5.dp))
        }
    }
}

Usage:

            RecentTabs(tabs = listOf(
                CustomeTabs(1,"Tab1", color = Color.Blue.toString()),
                CustomeTabs(2,"Tab2", color = Color.Gray.toString()),
                CustomeTabs(3,"Tab3", color = Color.Red.toString())
            ), onSelectedTab = {
                Log.d(TAG, "RecentScreen() called ${it.toString()}")
            })
Related