The Tab Layout is used to display tabs in a horizontal layout and it can be implemented with or without a ViewPager. Also, The layout handles interactions for a group of tabs such as scrolling behaviour, swipe gestures, tab selection,
animations and alignment.
In this example, the Tab Layout is going to be styled to have rounded corners and attached to a ViewPager.
Let’s dive right in.
Adding the design support library
Add the google material design library to your application build.gradle to use the TabLayout library
dependencies { // ... implementation 'com.google.android.material:material:<version>' // ... }
Working on the Activity Layout file support
Start by including the Tab Layout library in the required xml layout file:
<?xml version ="1.0" encoding ="utf-8"?> <androidx .constraintlayout.widget.ConstraintLayout xmlns:android ="http://schemas.android.com/apk/res/android" xmlns:tools ="http://schemas.android.com/tools" android:layout_width ="match_parent" android:layout_height ="match_parent" tools:context =".MainActivity">
<com .google.android.material.tabs.TabLayout android:id ="@+id/tab_layout" android:layout_width ="match_parent" android:layout_height ="27dp" app:tabGravity ="fill" app:tabIndicatorColor ="?attr/colorAccent" app:tabIndicatorGravity ="stretch" app:tabMaxWidth ="0dp" app:tabMode ="fixed" app:tabSelectedTextColor ="@android:color/white" app:tabTextAppearance ="@android:style/TextAppearance.Widget.TabWidget" app:tabTextColor ="?attr/colorPrimary"> </com .google.android.material.tabs.TabLayout>
<androidx .constraintlayout.widget.ConstraintLayout>
But this doesn’t make the corners rounded yet. Let’s make it so by wrapping into a CardView in the
activity_main.xml file and specifying the cardCornerRadius for rounded corners
<?xml version ="1.0" encoding ="utf-8"?> <androidx .constraintlayout.widget.ConstraintLayout xmlns:android ="http://schemas.android.com/apk/res/android" xmlns:tools ="http://schemas.android.com/tools" android:layout_width ="match_parent" android:layout_height ="match_parent" tools:context =".MainActivity">
<LinearLayout android:layout_width ="match_parent" android:layout_height ="wrap_content" android:orientation ="vertical" app:layout_constraintBottom_toBottomOf ="parent" app:layout_constraintEnd_toEndOf ="parent" app:layout_constraintStart_toStartOf ="parent" app:layout_constraintTop_toTopOf ="parent"/>
<com .google.android.material.card.MaterialCardView android:layout_width ="match_parent" android:layout_height ="wrap_content" android:layout_margin ="12dp" app:cardCornerRadius ="12dp" app:strokeColor ="?attr/colorAccent" app:strokeWidth ="1dp">
<com .google.android.material.tabs.TabLayout android:id ="@+id/tab_layout" android:layout_width ="match_parent" android:layout_height ="27dp" app:tabGravity ="fill" app:tabIndicatorColor ="?attr/colorAccent" app:tabIndicatorGravity ="stretch" app:tabMaxWidth ="0dp" app:tabMode ="fixed" app:tabSelectedTextColor ="@android:color/white" app:tabTextAppearance ="@android:style/TextAppearance.Widget.TabWidget" app:tabTextColor ="?attr/colorPrimary">
</com .google.android.material.tabs.TabLayout>
</com .google.android.material.card.MaterialCardView>
</LinearLayout >
<androidx .constraintlayout.widget.ConstraintLayout>
Great, we have rounded corners now.
As said above, this example would be implementing the ViewPager in the tab layout here, and this allows swipe gestures between fragments in the tab layout.
<androidx .viewpager.widget.ViewPager android:id ="@+id/pager" android:layout_width ="match_parent" android:layout_height ="match_parent" app:layout_behavior ="@string/appbar_scrolling_view_behavior"> />
The ViewPager is all set up now.
Working on the Fragments required
We are going to add two fragments to the tab layout:
<?xml version ="1.0" encoding ="utf-8"?> <RelativeLayout xmlns:android ="http://schemas.android.com/apk/res/android" xmlns:tools ="http://schemas.android.com/tools" android:layout_width ="match_parent" android:layout_height ="match_parent" tools:context =".fragments.Fragment1">
<TextView android:layout_width ="match_parent" android:layout_height ="match_parent" android:text ="Fragment1" android:gravity ="center"/>
</RelativeLayout >
import android.os.Bundle import androidx.fragment.app.Fragment import android.view.LayoutInflaterimport android.view.Viewimport android.view.ViewGroupimport com.example.roundedtablayout.R
class Fragment1 : Fragment() { private val fragmentList = ArrayList<Fragment> () private val fragmentTitleList = ArrayList<String> ()
override fun onCreateView ( inflater: LayoutInflater , container: ViewGroup ? , savedInstanceState: Bundle ? ): View ? { return inflater.inflate(R .layout.fragment_1, container, false ) } }
Note: The second fragment is implemented the same way the first fragment is displayed in this example
The ViewPager Adapter is setup to dynamically add fragments in the tab layout:
import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentManager import androidx.fragment.app.FragmentStatePagerAdapter
class ViewPagerAdapter (supportFragmentManager: FragmentManager ): FragmentStatePagerAdapter (supportFragmentManager){ private val fragmentList = ArrayList<Fragment> () private val fragmentTitleList = ArrayList<String> ()
override fun getItem (position: Int ): Fragment { return fragmentList[position] }
override fun getCount (): Int { return fragmentList.size }
override fun getPageTitle (position: Int ): CharSequence? { return fragmentTitleList[position] }
fun addFragment (fragment: Fragment , title: String ) { fragmentList.add(fragment) fragmentTitleList.add(title) }
}
Connecting it all together
Lastly, we need to link everything together in our MainActivity :
import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import androidx.viewpager.widget.ViewPager import com.example.roundedtablayout.adapter.ViewPagerAdapter import com.example.roundedtablayout.fragments.Fragment1 import com.example.roundedtablayout.fragments.Fragment2 import com.google.android.material.tabs.TabLayout import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() { lateinit var viewPager: ViewPager lateinit var tabLayout: TabLayout override fun onCreate (savedInstanceState: Bundle ? ) { super .onCreate(savedInstanceState) setContentView(R .layout.activity_main)
viewPager = findViewById(R .id.pager) tabLayout = findViewById(R .id.tab_layout) setAdapters()
}
private fun setAdapters () { val adapter = ViewPagerAdapter (supportFragmentManager) adapter.addFragment(Fragment1 (), "Tab 1") adapter.addFragment(Fragment2 (), "Tab 2") viewPager.adapter = adapter tabLayout.setupWithViewPager(pager) } }
When we run the app, this is what we are definitely going to have:
This is not all to it, as you can check out the official documentation to see what more, and also checkout the full code on github
Feel free to reach out to me on twitter to ask questions or give a feedback Thank you!