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)
            })
        }
    }
}

 

Jetpack COmpos tab layout with Viewpager

 

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, "")
            })
        }
    }
}
Jetpack COmpos tab layout with Viewpager example

 

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

 

Article Contributed By :
https://www.rrtutors.com/site_assets/profile/assets/img/avataaars.svg

4972 Views