Android TabLayout With ViewPager2 and Fragment in Kotlin

Till now, we have seen how to use TabLayout with ViewPager. In this tutorial, we will learn how to use Android TabLayout with ViewPager2 and Fragment in Kotlin.

Let’s have a quick demo of things we want to cover in this tutorial –

Output

Tutorialwing Kotlin Android TabLayout With ViewPager2 and Fragment in Kotlin With Example

Getting Started

As we already know, TabLayout is used to show different tabs in the application. We have already learnt how to use it with viewPager. In this article, we will implement it using ViewPager2. Note that ViewPager and ViewPager2 are two different widgets. In some way, we can say that ViewPager2 is an advanced version of ViewPager. So we should also learn how to implement TabLayout with ViewPager2.

Now, Let’s see how to implement it.

Creating New Project

At first, we will create an application.
So, follow steps below to create any android project in Kotlin –

Step Description
1. Open Android Studio (Ignore if already done).
2. Go to File => New => New Project. This will open a new window. Then, under Phone and Tablet section, select Empty Activity. Then, click Next.
3. In next screen, select project name as TabLayoutWithViewPager2. Then, fill other required details.
4. Then, clicking on Finish button creates new project.

Newbie in Android ?

Some very important concepts (Recommended to learn before you move ahead)

Before we move ahead, we need to setup for viewBinding to access Android WIDGET Using Kotlin file without using findViewById() method.

Setup ViewBinding

Add viewBinding true in app/build.gradle file.

 
 android { 
 	// OTHER CODE... 
 	buildFeatures { 
 		viewBinding true 
 	} 
 } 
 

Now, set content in activity using view binding.
Open MainActivity.kt file and write below code in it.

 
 class MainActivity : AppCompatActivity() { 
 	
 	private lateinit var binding: ActivityMainBinding 
 	
 	override fun onCreate(savedInstanceState: Bundle?) { 
 		super.onCreate(savedInstanceState) 
 		binding = ActivityMainBinding.inflate(layoutInflater) 
 		val view = binding.root 
 		setContentView(view) 
 	} 
 } 
 

Now, we can access view in Kotlin file without using findViewById() method.

Using TabLayout With ViewPager2 in Kotlin

Follow steps below to use TabLayout in newly created project –

  • Open res/values/strings.xml file. Then, add below code into it.
    <resources>
        <string name="app_name">TabLayoutWithViewPager2</string>
        <string name="second_fragment">Second Fragment</string>
        <string name="first_fragment">First Fragment</string>
    </resources>
    
  • In this article, we are using ViewPager2 with Fragments. So, we need to create fragments first. Follow steps below to add it –

    1. Create First Fragment

      Create new xml file, first_fragment.xml, in res/layout folder. Then, add below code in it –

      <?xml version="1.0" encoding="utf-8"?>
      <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:app="http://schemas.android.com/apk/res-auto"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:background="@android:color/holo_blue_light">
      
          <TextView
              android:id="@+id/label"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              app:layout_constraintBottom_toBottomOf="parent"
              app:layout_constraintEnd_toEndOf="parent"
              app:layout_constraintStart_toStartOf="parent"
              app:layout_constraintTop_toTopOf="parent" />
      
      </androidx.constraintlayout.widget.ConstraintLayout>
      

      In fragment, we are just showing text message when this fragment is shown to user.

      Now, Create new Kotlin file, FirstFragment.kt, in com.tutorialwing.tablayoutwithviewpager2 package. Then, add below code in it –

      package com.tutorialwing.tablayoutwithviewpager2
      
      import android.os.Bundle
      import android.view.LayoutInflater
      import android.view.View
      import android.view.ViewGroup
      import androidx.fragment.app.Fragment
      import com.tutorialwing.tablayoutwithviewpager2.databinding.FirstFragmentBinding
      
      class FirstFragment : Fragment() {
      
      	private lateinit var binding: FirstFragmentBinding
      
      	override fun onCreateView(
      		inflater: LayoutInflater,
      		container: ViewGroup?,
      		savedInstanceState: Bundle?
      	): View {
      		binding = FirstFragmentBinding.inflate(layoutInflater)
      		return binding.root
      	}
      
      	override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
      		super.onViewCreated(view, savedInstanceState)
      
      		setupData()
      	}
      
      	private fun setupData() {
      		binding.label.text = getString(R.string.first_fragment)
      	}
      }
      

      Here, we set text to textView in setupData() called from onViewCreated() method.

    2. Create Second Fragment

      Now, we will create second fragment and it’s ui. So, create new xml file, second_fragment.xml, in res/layout folder. Then, add below code in it –

      <?xml version="1.0" encoding="utf-8"?>
      <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:app="http://schemas.android.com/apk/res-auto"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:background="@android:color/holo_red_light">
      
          <TextView
              android:id="@+id/label"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              app:layout_constraintBottom_toBottomOf="parent"
              app:layout_constraintEnd_toEndOf="parent"
              app:layout_constraintStart_toStartOf="parent"
              app:layout_constraintTop_toTopOf="parent" />
      
      </androidx.constraintlayout.widget.ConstraintLayout>
      

      Here, we want to show text in ui. So, we have added only textView.

      Now, we will create Kotlin file, SecondFragment.kt, in com.tutorialwing.tablayoutwithviewpager2 package folder. Then, add below code in it –

      package com.tutorialwing.tablayoutwithviewpager2
      
      import android.os.Bundle
      import android.view.LayoutInflater
      import android.view.View
      import android.view.ViewGroup
      import androidx.fragment.app.Fragment
      import com.tutorialwing.tablayoutwithviewpager2.databinding.SecondFragmentBinding
      
      class SecondFragment : Fragment() {
      
      	private lateinit var binding: SecondFragmentBinding
      
      	override fun onCreateView(
      		inflater: LayoutInflater,
      		container: ViewGroup?,
      		savedInstanceState: Bundle?
      	): View {
      		binding = SecondFragmentBinding.inflate(layoutInflater)
      		return binding.root
      	}
      
      	override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
      		super.onViewCreated(view, savedInstanceState)
      
      		setupData()
      	}
      
      	private fun setupData() {
      		binding.label.text = getString(R.string.second_fragment)
      	}
      }
      
  • Create An Adapter for ViewPager2

    Now, we need to create adapter for ViewPager2 that provides data to ViewPager2 while creating ui. So, create new Kotlin file, ViewPagerAdapter.kt, in com.tutorialwing.tablayoutwithviewpager2 package. Then, add below code in it –

    package com.tutorialwing.tablayoutwithviewpager2
    
    import androidx.fragment.app.Fragment
    import androidx.fragment.app.FragmentActivity
    import androidx.viewpager2.adapter.FragmentStateAdapter
    
    class ViewPagerAdapter(fragmentActivity: FragmentActivity, private var totalCount: Int) :
    	FragmentStateAdapter(fragmentActivity) {
    
    	override fun getItemCount(): Int {
    		return totalCount
    	}
    
    	override fun createFragment(position: Int): Fragment {
    		return when (position) {
    			0 -> FirstFragment()
    			1 -> SecondFragment()
    			else -> FirstFragment()
    		}
    	}
    }
    

    Here,

    • createFragment(): Inside this method, new instance of fragment is being created based on item position. For 1st position, FirstFragment is being created and returned. For 2nd position, SecondFragment is being created and returned.
  • Open res/layout/activity_main.xml file. Then, add below code in it –
    <?xml version="1.0" encoding="utf-8"?>
    <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        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/tabLayout"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
    
        <androidx.viewpager2.widget.ViewPager2
            android:id="@+id/viewPager"
            android:layout_width="0dp"
            android:layout_height="0dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/tabLayout">
    
        </androidx.viewpager2.widget.ViewPager2>
    
    </androidx.constraintlayout.widget.ConstraintLayout>
    
  • We can also access it in Kotlin File, MainActivity.kt, as below –

    package com.tutorialwing.tablayoutwithviewpager2
    
    import android.os.Bundle
    import androidx.appcompat.app.AppCompatActivity
    import com.google.android.material.tabs.TabLayoutMediator
    import com.tutorialwing.tablayoutwithviewpager2.databinding.ActivityMainBinding
    
    
    class MainActivity : AppCompatActivity() {
    
    	private lateinit var binding: ActivityMainBinding
    
    	override fun onCreate(savedInstanceState: Bundle?) {
    		super.onCreate(savedInstanceState)
    
    		binding = ActivityMainBinding.inflate(layoutInflater)
    		setContentView(binding.root)
    
    		setupViewPager()
    		setupTabLayout()
    	}
    
    	private fun setupTabLayout() {
    		TabLayoutMediator(
    			binding.tabLayout, binding.viewPager
    		) { tab, position -> tab.text = "Tab " + (position + 1) }.attach()
    	}
    
    	private fun setupViewPager() {
    		val adapter = ViewPagerAdapter(this, 2)
    		binding.viewPager.adapter = adapter
    	}
    
    	override fun onBackPressed() {
    		val viewPager = binding.viewPager
    		if (viewPager.currentItem == 0) {
    			// If the user is currently looking at the first step, allow the system to handle the
    			// Back button. This calls finish() on this activity and pops the back stack.
    			super.onBackPressed()
    		} else {
    			// Otherwise, select the previous step.
    			viewPager.currentItem = viewPager.currentItem - 1
    		}
    	}
    }
    

Now, run the application. We will get output as below –
Tutorialwing Kotlin Android TabLayout With ViewPager2 and Fragment in Kotlin With Example

That’s end of tutorial on Android TabLayout With ViewPager2 and Fragment in Kotlin.

Leave a Reply