Tabs in Jetpack Compose using Official API
This story will show how to create Tab layout in Jetpack Compose using Official Compose Foundation Dependency.
I have written another story about ViewPager in Jetpack Compose using Official API. You can read it there.
Tabs are a very common design to organize information in different sections. We already are familiar about how to implement in view based design layouts But in this article we will implement it using Jetpack Compose.
Lets get started! 🚀
Dependency
Tabs API was initially part of accompanist But from Compose 1.4.0+ its part of official API. you need to add Compose Foundation dependency inside the project. You can see latest version here
implementation 'androidx.compose.foundation:foundation:1.4.0-rc01'
Your project might give errors because you might still be on an older version of Compose Compiler. You need to upgrade your Compose Compiler version to at least 1.4.0 and to achieve that you might also need to update your Kotlin version. You can see Kotlin version to Compose Compiler version mapping here.
You should update Compose Compiler version in gradle files as below
composeOptions {
kotlinCompilerExtensionVersion '1.4.3'
}
Preparation
Before implementation we need to prepare Tabs. To hold tab data we need to create a TabItem
data class.
TabItem
takes title
and icon
representing a tab. It also takes a composable screen
which will be shown when the user taps on that particular tab UI.
Lets create generic composable function representing a Tab screen.
To keep it simple for this example we are just passing a text to TabScreen
.
Below creating list of Tabs we want to show
Implementation
lets implement Tab Layout screen.
val pagerState = rememberPagerState()
val coroutineScope = rememberCoroutineScope()
rememberPagerState
is required to manage pager state
rememberCoroutineScope
is required to perform scroll animation on pagerState
whenever user taps on any tab. Its used to launch coroutine outside composable function.
rememberCoroutineScope
is a composable which is called to get a coroutine scope. Its tied to the composable function from where its called and gets canceled when that composable does not exist. i.e you can launch coroutines using this scope without worrying about lifecycle of coroutines.
Below creating TabRow
TabRow
is a container for all tabs.
We are iterating tabs
using forEachIndexed
, these tabs
data we already created in preparation above. We are populating each tab here inside TabRow
using Tab
composable.
Tab
composable is representation of single tab with following properties
selected = index == pagerState.currentPage
handles selection state of a Tab. if index of tab is same as pager current page then tab is in selected state.
text
and icon
for tab, these are optional
onClick
listens for tap events on tab and calls pagerState.animateScrollToPage(index).
It moves pager to the selected tab calling suspend function which is launched within a coroutine scope.
Now Lets see complete code with HorizontalPager
HorizontalPager
taking total page counts and pagerState
. Its same pagerState
used in TabRow
and Tab
composables and it automatically links them together.
Thats it! hope you liked it.
Further Points
ScrollableTabRow
composable is also available, which you can use if you have more tabs and needs a scroller to show them all. It depends upon need- Before this api was officially introduced in Compose Foundation dependency, it was available in accompanist dependency. If you have already used from accompanist and you want to move to official dependency then there is migration guide available here
Sources
- Tabs Material Design 3
- Compose Foundation — Official support but its still in Experimental
- TabRow — represents a TabRow
- Tab — represents a single Tab
- Migration guide from accompanist to Official API
GitHub Project
Link is below