Jetpack Compose Viewpager - Create Tablayout with Viewpager
Last updated Nov 01, 2021 In this Jetpack compose tutorial we will learn How to Create TabLayout with View Pager using Jetpack compose in Android application.
To slide between pages we use ViewPager in traditional android but in Jetpack compose equivalent to ViewPager is Pager.
Let's get started
Step 1: Create android application in android studio
Step 2: Follow step for setup Jetpack Compose with Android Studio
To use pager we need to add dependency in build.gradle
implementation "com.google.accompanist:accompanist-pager:0.20.0"
|
Lets create Screen for tab
Here we are using 3 Screen : Home,Contacts and Settings Screen
sealed class TabItem(
val index:Int,
val icon: ImageVector,
val title: String,
val screenToLoad: @Composable () -> Unit
) {
object Home : TabItem(0, Icons.Default.Home, "Home", {
HomeScreenForTab()
})
object Contacts : TabItem(2, Icons.Default.Contacts, "Contacts", {
ContactScreenForTab()
})
object Settings : TabItem(1, Icons.Default.Settings, "Settings", {
SettingsScreenForTab()
})
}
@Composable
fun HomeScreenForTab() {
Column(
content = {
Text(text = "You are in Home Screen")
}, modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
)
}
@Composable
fun ContactScreenForTab() {
Column(
content = {
Text(text = "You are in Contacts Screen")
}, modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
)
}
@Composable
fun SettingsScreenForTab() {
Column(
content = {
Text(text = "You are in Settings Screen")
}, modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
)
}
|
Create a list of tab item
private val tabs = listOf(
TabItem.Home,
TabItem.Settings,
TabItem.Contacts
)
|
To implement TabLayout we need 4 components
1. HorizontalPager : which is used to slide pages horizontally.
2. PagerState: A state which is used to control horizontal scrolling of pages.
3. Tab: which represent single page can be used inside TabRow or ScrollableTabRow
4. TabRow: contain multiple Tabs
Lets create a composable function for Horizontal Pager which will take pagerState and list of tabItems
@ExperimentalPagerApi
@Composable
fun TabPage(pagerState: PagerState, tabItems: List) {
HorizontalPager(
count = tabs.size,
state = pagerState
) { index ->
tabItems[index].screenToLoad()
}
}
|
Tabs With Only Text
@Composable
fun TextTabLayout(
tabs: List,
selectedIndex: Int,
onPageSelected: ((tabItem: TabItem) -> Unit)
) {
TabRow(selectedTabIndex = selectedIndex) {
tabs.forEachIndexed { index, tabItem ->
Tab(selected = index == selectedIndex, onClick = {
onPageSelected(tabItem)
}, text = {
Text(text = tabItem.title)
})
}
}
}
|

Tabs With Only Icon
@Composable
fun IconTabLayout(
tabs: List,
selectedIndex: Int,
onPageSelected: ((tabItem: TabItem) -> Unit)
) {
TabRow(selectedTabIndex = selectedIndex) {
tabs.forEachIndexed { index, tabItem ->
Tab(selected = index == selectedIndex, onClick = {
onPageSelected(tabItem)
}, icon = {
Icon(tabItem.icon, "")
})
}
}
}
|
Create Scrollable Tabs
@Composable
fun ScrollableTabLayout(
tabs: List,
selectedIndex: Int,
onPageSelected: ((tabItem: TabItem) -> Unit)
) {
ScrollableTabRow(selectedTabIndex = selectedIndex) {
tabs.forEachIndexed { index, tabItem ->
Tab(selected = index == selectedIndex, onClick = {
onPageSelected(tabItem)
}, text = {
Text(text = tabItem.title)
}, icon = {
Icon(tabItem.icon, "")
})
}
}
}
|
Create Tab with Icon and Text with Jetpack Compose
@ExperimentalPagerApi
@Composable
fun IconWithTextTabLayout(
tabs: List,
selectedIndex: Int,
onPageSelected: ((tabItem: TabItem) -> Unit)
) {
TabRow(selectedTabIndex = selectedIndex) {
tabs.forEachIndexed { index, tabItem ->
Tab(selected = index == selectedIndex, onClick = {
onPageSelected(tabItem)
}, text = {
Text(text = tabItem.title)
}, icon = {
Icon(tabItem.icon, "")
})
}
}
}
|
use one of the above layout
@Composable
fun TabLayoutDemo() {
JetPackTheme(
darkTheme = true,
) {
val pagerState = rememberPagerState()
Scaffold(
modifier = Modifier.fillMaxSize(),
content = {
TabPage(tabItems = tabs, pagerState = pagerState)
},
topBar = {
val coroutineScope = rememberCoroutineScope()
Column(content = {
TopAppBar(title = { Text("Tab Layout Demo") }
)
IconWithTextTabLayout(
tabs,
selectedIndex = pagerState.currentPage,
onPageSelected = { tabItem: TabItem ->
coroutineScope.launch {
pagerState.animateScrollToPage(tabItem.index)
}
})
})
},
)
}
}
|
Complete code for Jetpack Compose Tablayout with View Pager example
package com.example.jetpack
import android.os.Bundle
import android.view.WindowManager
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.*
import androidx.compose.material.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Contacts
import androidx.compose.material.icons.filled.Home
import androidx.compose.material.icons.filled.Settings
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.tooling.preview.Preview
import com.example.jetpack.ui.theme.JetPackTheme
import com.google.accompanist.pager.*
import kotlinx.coroutines.launch
class MainActivity : ComponentActivity() {
@ExperimentalPagerApi
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE)
setContent {
TabLayoutDemo()
}
}
}
private val tabs = listOf(
TabItem.Home,
TabItem.Settings,
TabItem.Contacts
)
sealed class TabItem(
val index:Int,
val icon: ImageVector,
val title: String,
val screenToLoad: @Composable () -> Unit
) {
object Home : TabItem(0, Icons.Default.Home, "Home", {
HomeScreenForTab()
})
object Contacts : TabItem(2, Icons.Default.Contacts, "Contacts", {
ContactScreenForTab()
})
object Settings : TabItem(1, Icons.Default.Settings, "Settings", {
SettingsScreenForTab()
})
}
@Composable
fun HomeScreenForTab() {
Column(
content = {
Text(text = "You are in Home Screen")
}, modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
)
}
@Composable
fun ContactScreenForTab() {
Column(
content = {
Text(text = "You are in Contact Us Screen")
}, modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
)
}
@Composable
fun SettingsScreenForTab() {
Column(
content = {
Text(text = "You are in Settings Screen")
}, modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
)
}
@ExperimentalPagerApi
@Composable
fun TabLayoutDemo() {
JetPackTheme(
darkTheme = true,
) {
val pagerState = rememberPagerState()
Scaffold(
modifier = Modifier.fillMaxSize(),
content = {
TabPage(tabItems = tabs, pagerState = pagerState)
},
topBar = {
val coroutineScope = rememberCoroutineScope()
Column(content = {
TopAppBar(title = { Text("Tab Layout Demo") }
)
//Replace here with TextTabLayout or ScrollableTabLayout or IconTabLayout
IconWithTextTabLayout(
tabs,
selectedIndex = pagerState.currentPage,
onPageSelected = { tabItem: TabItem ->
coroutineScope.launch {
pagerState.animateScrollToPage(tabItem.index)
}
})
})
},
)
}
}
@ExperimentalPagerApi
@Composable
fun TabPage(pagerState: PagerState, tabItems: List) {
HorizontalPager(
count = tabs.size,
state = pagerState
) { index ->
tabItems[index].screenToLoad()
}
}
@ExperimentalPagerApi
@Composable
fun IconWithTextTabLayout(
tabs: List,
selectedIndex: Int,
onPageSelected: ((tabItem: TabItem) -> Unit)
) {
TabRow(selectedTabIndex = selectedIndex) {
tabs.forEachIndexed { index, tabItem ->
Tab(selected = index == selectedIndex, onClick = {
onPageSelected(tabItem)
}, text = {
Text(text = tabItem.title)
}, icon = {
Icon(tabItem.icon, "")
})
}
}
}
@Composable
fun TextTabLayout(
tabs: List,
selectedIndex: Int,
onPageSelected: ((tabItem: TabItem) -> Unit)
) {
TabRow(selectedTabIndex = selectedIndex) {
tabs.forEachIndexed { index, tabItem ->
Tab(selected = index == selectedIndex, onClick = {
onPageSelected(tabItem)
}, text = {
Text(text = tabItem.title)
})
}
}
}
@Composable
fun ScrollableTabLayout(
tabs: List,
selectedIndex: Int,
onPageSelected: ((tabItem: TabItem) -> Unit)
) {
ScrollableTabRow(selectedTabIndex = selectedIndex) {
tabs.forEachIndexed { index, tabItem ->
Tab(selected = index == selectedIndex, onClick = {
onPageSelected(tabItem)
}, text = {
Text(text = tabItem.title)
}, icon = {
Icon(tabItem.icon, "")
})
}
}
}
@Composable
fun IconTabLayout(
tabs: List,
selectedIndex: Int,
onPageSelected: ((tabItem: TabItem) -> Unit)
) {
TabRow(selectedTabIndex = selectedIndex) {
tabs.forEachIndexed { index, tabItem ->
Tab(selected = index == selectedIndex, onClick = {
onPageSelected(tabItem)
}, icon = {
Icon(tabItem.icon, "")
})
}
}
}
@ExperimentalPagerApi
@Preview(showBackground = true)
@Composable
fun DefaultPreview() {
TabLayoutDemo()
}
|
Conclusion: In this Jetpack compose Tutorial we covered create Tablyout with Jetpack compose and different properties of Tablayout and Jetpack compose ViewPager Example