4
4
.
.
4
4
.
.
3
3
T
T
a
a
b
b
R
R
o
o
w
w
I
I
n
n
f
f
o
o
[
[
R
R
]
]
TabRow display row of Tabs & uses following Parameters (all the logic needs to be implemented in the Tabs themselves).
selectedTabIndex index of the currently selected tab
tabs list of tabs that will be shown in the TabRow (you can use Tab)
indicator is used to define how selected tab should look like
scrollable if true then tabs will be scrollable (if there are too many of the to fit on the TabRow)
if false then all the tabs will be visible (if needed compressed in the space provided)
Syntax
TabRow(
tabs = {
Text("Tab 0")
Text("Tab 1")
Text("Tab 2")
}
)
Content
Basic Example (Show each Tab as Text. You can click to select)
Custom Selection (We define how selected Tab should look like)
Custom Tab (We create Custom Tab to avoid repeating code)
Add Content (When Tab is selected specific content is displayed on the remaining screen)
Built in Tab View (Like Custom Tab but already part of the system)
B
B
a
a
s
s
i
i
c
c
E
E
x
x
a
a
m
m
p
p
l
l
e
e
In this example we create simple TabBar where selected Tab is underscored with white line (default indicator behaviour).
For that purpose selectedTabIndex needs to be populated by State variable (so that it can react to changes).
MainActivity.kt
package com.example.myapplication
import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.foundation.*
import androidx.compose.material.TabRow
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.setContent
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
val selectedTabIndex = remember { mutableStateOf(0) }
TabRow(
selectedTabIndex = selectedTabIndex.value,
tabs = {
Text("Tab 0" ,Modifier.clickable (onClick = { selectedTabIndex.value = 0 }))
Text("Tab 1" ,Modifier.clickable (onClick = { selectedTabIndex.value = 1 }))
Text("Tab 2" ,Modifier.clickable (onClick = { selectedTabIndex.value = 2 }))
}
)
}
}
}
Output
C
C
u
u
s
s
t
t
o
o
m
m
S
S
e
e
l
l
e
e
c
c
t
t
i
i
o
o
n
n
In this example we define our custom appearance for selected Tab and are no longer using selectedTabIndex & indicator.
MainActivity.kt
package com.example.myapplication
import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.foundation.*
import androidx.compose.foundation.layout.*
import androidx.compose.material.*
import androidx.compose.runtime.*
import androidx.compose.ui.*
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.setContent
import androidx.compose.ui.unit.dp
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
val selectedTabIndex = remember { mutableStateOf(0) }
val colorSelected = Color.Green
val colorDeselected = Color.Unset
TabRow(
selectedTabIndex = 0,
indicator = {},
tabs = {
Text(
text = "Tab 0",
modifier = Modifier
.clickable (onClick = { selectedTabIndex.value = 0 })
.background(color = if(selectedTabIndex.value == 0) { colorSelected } else { colorDeselected })
)
Text(
text = "Tab 1",
modifier = Modifier
.clickable (onClick = { selectedTabIndex.value = 1 })
.background(color = if(selectedTabIndex.value == 1) { colorSelected } else { colorDeselected })
)
Text(
text = "Tab 2",
modifier = Modifier
.clickable (onClick = { selectedTabIndex.value = 2 })
.background(color = if(selectedTabIndex.value == 2) { colorSelected } else { colorDeselected })
)
}
)
}
}
}
Output
C
C
u
u
s
s
t
t
o
o
m
m
T
T
a
a
b
b
In this example we simplify previous example by creating custom tab with myTab all the necessary logic.
MainActivity.kt
package com.example.myapplication
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.foundation.*
import androidx.compose.material.TabRow
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.setContent
val colorSelected = Color.Green
val colorDeselected = Color.Unset
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
val selectedTabIndex = remember { mutableStateOf(0) }
TabRow(
selectedTabIndex = 0,
indicator = {},
tabs = {
myTab("Tab 0", 0, selectedTabIndex.value) { newIndex -> selectedTabIndex.value = newIndex }
myTab("Tab 1", 1, selectedTabIndex.value) { newIndex -> selectedTabIndex.value = newIndex }
myTab("Tab 2", 2, selectedTabIndex.value) { newIndex -> selectedTabIndex.value = newIndex }
}
)
}
}
}
@Composable
fun myTab(text: String, index: Int, selectedTabIndex: Int, updateIndex: (Int) -> Unit) {
Text(
text = text,
modifier = Modifier
.clickable (onClick = { updateIndex(index) })
.background(color = if (selectedTabIndex == index) { colorSelected } else { colorDeselected } )
)
}
Output
A
A
d
d
d
d
C
C
o
o
n
n
t
t
e
e
n
n
t
t
Int his example we wrap everything in a Box to display specific content for selected Tab.
MainActivity.kt
package com.example.myapplication
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.foundation.*
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.layout.Box
import androidx.compose.material.TabRow
import androidx.compose.runtime.*
import androidx.compose.ui.*
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.setContent
val colorSelected = Color.Green
val colorDeselected = Color.Unset
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
val selectedTabIndex = remember { mutableStateOf(0) }
Box(Modifier.fillMaxSize()) {
TabRow(
modifier = Modifier.align(Alignment.BottomStart), //Without this goes on top
selectedTabIndex = 0,
indicator = {},
tabs = {
myTab("Tab 0", 0, selectedTabIndex.value) { newIndex -> selectedTabIndex.value = newIndex }
myTab("Tab 1", 1, selectedTabIndex.value) { newIndex -> selectedTabIndex.value = newIndex }
myTab("Tab 2", 2, selectedTabIndex.value) { newIndex -> selectedTabIndex.value = newIndex }
}
)
when(selectedTabIndex.value) {
0 -> Text("Content of Tab 0", Modifier.align(Alignment.Center))
1 -> Text("Content of Tab 1", Modifier.align(Alignment.Center))
2 -> Text("Content of Tab 2", Modifier.align(Alignment.Center))
}
}
}
}
}
@Composable
fun myTab(text: String, index: Int, selectedTabIndex: Int, updateIndex: (Int) -> Unit) {
Text(
text = text,
modifier = Modifier
.clickable (onClick = { updateIndex(index) })
.background(color = if(selectedTabIndex == index) { colorSelected} else { colorDeselected } )
)
}
Output
B
B
u
u
i
i
l
l
t
t
i
i
n
n
T
T
a
a
b
b
V
V
i
i
e
e
w
w
[
[
R
R
]
]
In this example we use built in Tab View (this is similar to using our Custom MyTab except this one is part of the system).
In this example we define three Tabs and for each we define font color when it is selected or deselected.
When Tab is selected corresponding content is shown on the screen.
MainActivity.kt
package com.example.myapplication
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.foundation.Text
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material.Tab
import androidx.compose.material.TabRow
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.setContent
val colorSelected = Color.Green
val colorDeselected = Color.Unset
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
val selectedTabIndex = remember { mutableStateOf(0) }
Box(Modifier.fillMaxSize()) {
TabRow(
modifier = Modifier.align(Alignment.TopStart), //Without this goes on top
selectedTabIndex = selectedTabIndex.value,
tabs = {
Tab(
selected = selectedTabIndex.value == 0,
onClick = { selectedTabIndex.value = 0 },
unselectedContentColor = Color.Green,
selectedContentColor = Color.Red
)
{
Text("Tab 0")
}
Tab(
selected = selectedTabIndex.value == 1,
onClick = { selectedTabIndex.value = 1 },
unselectedContentColor = Color.Green,
selectedContentColor = Color.Red
)
{
Text("Tab 1")
}
Tab(
selected = selectedTabIndex.value == 2,
onClick = { selectedTabIndex.value = 2 },
unselectedContentColor = Color.Green,
selectedContentColor = Color.Red
)
{
Text("Tab 2")
}
}
)
when(selectedTabIndex.value) {
0 -> Text("Content of Tab 0", Modifier.align(Alignment.Center))
1 -> Text("Content of Tab 1", Modifier.align(Alignment.Center))
2 -> Text("Content of Tab 2", Modifier.align(Alignment.Center))
}
}
}
}
}
Output