TabLayout With ViewPager2, AppBarLayout and Toolbar

In this article, we will learn to implement Android TabLayout With ViewPager2 AppBarLayout and Toolbar in Kotlin. We will see how to design scrollable ui using those widgets in android application.

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

Output

Tutorialwing Kotlin Android TabLayout With ViewPager2, AppBarLayout and Toolbar in Kotlin With Example

Getting Started

We have already seen how to design ui using TabLayout and ViewPager2. We have also noticed that we can n’t scroll toolbar and TabLayout up and down. In this article, we will fix this issue using AppBarLayout.

Let’s start now!

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 TabLayoutWithAppBarLayout. 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 Widgets 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 AppBarLayout, ViewPager2 in Kotlin

Follow steps below to use these widgets in newly created project –

  • Open res/values/strings.xml file. Then, add below code into it.
    <resources>
        <string name="app_name">TabLayoutWithAppBarLayout</string>
        <string name="music_fragment">Music Fragment</string>
        <string name="movie_fragment">Movie Fragment</string>
    </resources>
    
  • Create Fragments For ViewPager2

    In our application, we are going to design two tabs – (one for Music List and Another for Movie List). So, we need two fragments for ViewPager2 as well to display ui for each tab. Follow steps below to create fragments now –

    1. Create First Fragment

      Create new xml file, movie_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">
      
          <ImageView
              android:id="@+id/imageView"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:contentDescription="Movie Image"
              app:layout_constraintBottom_toBottomOf="parent"
              app:layout_constraintEnd_toEndOf="parent"
              app:layout_constraintStart_toStartOf="parent"
              app:layout_constraintTop_toTopOf="parent"
              app:srcCompat="@drawable/ic_movie" />
      
          <TextView
              android:id="@+id/label"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:textSize="18sp"
              android:textStyle="bold"
              app:layout_constraintEnd_toEndOf="parent"
              app:layout_constraintStart_toStartOf="parent"
              app:layout_constraintTop_toBottomOf="@+id/imageView" />
      
      </androidx.constraintlayout.widget.ConstraintLayout>
      

      Here,

      • We are going to display name and image in ui. So, we have used TextView and ImageView. We have used app:srcCompat=”” attribute to set image from drawable folder to ImageView.

      Now, we need to create new Kotlin file, MovieFragment.kt, in com.tutorialwing.tablayoutwithviewpager2 package. Then, add below code in it –

      package com.tutorialwing.tablayoutwithappbarlayout
      
      import android.os.Bundle
      import android.view.LayoutInflater
      import android.view.View
      import android.view.ViewGroup
      import androidx.fragment.app.Fragment
      import com.tutorialwing.tablayoutwithappbarlayout.databinding.MovieFragmentBinding
      
      class MovieFragment : Fragment() {
      
      	private lateinit var binding: MovieFragmentBinding
      
      	override fun onCreateView(
      		inflater: LayoutInflater,
      		container: ViewGroup?,
      		savedInstanceState: Bundle?
      	): View {
      		binding = MovieFragmentBinding.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.movie_fragment)
      	}
      }
      
    2. Create Second Fragment

      Now, we need to create another fragment to display music ui. So, create new xml file, music_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">
      
          <ImageView
              android:id="@+id/imageView"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:contentDescription="Music Image"
              app:layout_constraintBottom_toBottomOf="parent"
              app:layout_constraintEnd_toEndOf="parent"
              app:layout_constraintStart_toStartOf="parent"
              app:layout_constraintTop_toTopOf="parent"
              app:srcCompat="@drawable/ic_music" />
      
          <TextView
              android:id="@+id/label"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:textSize="18sp"
              android:textStyle="bold"
              app:layout_constraintEnd_toEndOf="parent"
              app:layout_constraintStart_toStartOf="parent"
              app:layout_constraintTop_toBottomOf="@+id/imageView" />
      
      </androidx.constraintlayout.widget.ConstraintLayout>
      

      It’s same as movie fragment. We have used imageView and textView both in it. Now, we will create new Kotlin file, MusicFragment.kt, in com.tutorialwing.tablayoutwithviewpager2 folder. Then, add below code in it –

      package com.tutorialwing.tablayoutwithappbarlayout
      
      import android.os.Bundle
      import android.view.LayoutInflater
      import android.view.View
      import android.view.ViewGroup
      import androidx.fragment.app.Fragment
      import com.tutorialwing.tablayoutwithappbarlayout.databinding.MusicFragmentBinding
      
      class MusicFragment : Fragment() {
      
      	private lateinit var binding: MusicFragmentBinding
      
      	override fun onCreateView(
      		inflater: LayoutInflater,
      		container: ViewGroup?,
      		savedInstanceState: Bundle?
      	): View {
      		binding = MusicFragmentBinding.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.music_fragment)
      	}
      }
      
  • Create Adapter for ViewPager2

    Now, we need to create adapter for viewPager2. So, create new Kotlin file, ViewPagerAdapter.kt, in com.tutorialwing.tablayoutwithviewpager2 package. Then, add below code in it –

    package com.tutorialwing.tablayoutwithappbarlayout
    
    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 -> MovieFragment()
    			1 -> MusicFragment()
    			else -> MovieFragment()
    		}
    	}
    }
    

    Here, we are creating new instance of fragment based on selected tab position.

  • Open res/layout/activity_main.xml file. Then, add below code in it –
    <?xml version="1.0" encoding="utf-8"?>
    <androidx.coordinatorlayout.widget.CoordinatorLayout 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">
    
        <com.google.android.material.appbar.AppBarLayout
            android:id="@+id/appBarLayout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
    
            <androidx.appcompat.widget.Toolbar
                android:id="@+id/toolBar"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="?attr/colorPrimary"
                android:minHeight="?attr/actionBarSize"
                android:theme="?attr/actionBarTheme"
                app:layout_anchor="@+id/appBarLayout"
                app:layout_anchorGravity="bottom|center"
                app:layout_scrollFlags="scroll|enterAlways" />
    
            <com.google.android.material.tabs.TabLayout
                android:id="@+id/tabLayout"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="?attr/colorPrimary"
                app:tabIndicatorColor="#a0a0a0"
                app:tabIndicatorHeight="3dp"
                app:tabMode="fixed"
                app:tabSelectedTextColor="#a0a0a0"
                app:tabTextColor="#000000" />
    
        </com.google.android.material.appbar.AppBarLayout>
    
        <androidx.core.widget.NestedScrollView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:fillViewport="true"
            app:layout_behavior="@string/appbar_scrolling_view_behavior">
    
            <androidx.viewpager2.widget.ViewPager2
                android:id="@+id/viewPager"
                android:layout_width="match_parent"
                android:layout_height="match_parent" />
    
        </androidx.core.widget.NestedScrollView>
    
    </androidx.coordinatorlayout.widget.CoordinatorLayout>
    

    Notice how we have used android tabLayout with appBarLayout and toolBar in Kotlin. When we scroll ui up, only tabs and viewPager2 are visible, toolBar is hidden in this case. It becomes visible again when ui is scrolled down.

  • We can also access it in Kotlin File, MainActivity.kt, as below –

    package com.tutorialwing.tablayoutwithappbarlayout
    
    import androidx.appcompat.app.AppCompatActivity
    import android.os.Bundle
    import com.google.android.material.tabs.TabLayoutMediator
    import com.tutorialwing.tablayoutwithappbarlayout.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)
    
    		setSupportActionBar(binding.toolBar)
    
    		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
    		}
    	}
    }
    

    Here,

    1. onCreate(): Inside this method, we set toolbar as actionBar in activity. Then, we call methods to setup viewPager2 and tabLayout.
    2. setupTabLayout(): In this method, we set tabLayout and viewPager2 using TabLayoutMediator .
    3. setupViewPager(): In this method, we setup ViewPager2 and it’s adapter.
    4. onBackPressed(): This method handles back button press.

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

That’s end of tutorial on Android TabLayout With AppBarLayout and Toolbar in Kotlin.

Leave a Reply