Intro to Android Development
  • Welcome
  • Syllabus
  • Hack Challenge
  • Resources
    • Lecture Videos
    • Ed Discussion
    • Git & GitHub Help/How-To
    • Setting up Android Studio
    • Starting an Android Studio Project & Making an Emulator
    • Importing, Exporting, & Submitting Your Projects to CMS
  • SP25 Course Material
    • Week 1 | Course Logistics, Kotlin, & Basic UI
      • Relevant Links
      • Demo/Lecture: Eatery Card
      • A0: Eatery Card (Follow-Along)
    • Week 2 | States, Components, LazyColumn
      • Relevant Links
      • Demo: Todo List
      • A2: Shopping List
    • Week 3 | Navigation & Animations
      • Relevant Links
      • Demo: Onboarding
      • A3: Stock Trading (RobbingGood)
    • Week 4 | MVVM and Flows
      • Relevant Links
      • Demo: Eatery Card 2
      • A4: Chat of a Lifetime
    • Week 5 | Dumb Components & UIEvents
      • Relevant Links
      • Demo: Music Player
      • A5: Rate My Vibe
    • Week 6 | Coroutines, Networking, JSON
      • Relevant Links
      • Demo: Retrofit
      • A6: You Should Even Lift, Bro.
  • Bonus Week | Android Job Search
    • Relevant Links
    • Android Technical Interview Question!
  • Textbook
    • 1. Introduction to the Editor and Views
      • 1.1 Introduction to the Editor
      • 1.2 SDK Management
      • 1.3 Kotlin Overview
      • 1.4 Views
      • 1.5 Android Studio Project Demo + Understanding The Editor
    • 2. Jetpack Compose
      • 2.1 Introduction
      • 2.2 Layouts
      • 2.3 Modifiers
      • 2.4 Animations
      • 2.5 Lazy Lists
      • 2.6 Reactive UI
    • 3. Intents and Manifest
      • 3.1 Activities
      • 3.2 Implicit Intents
      • 3.3 Explicit Intents
      • 3.4 Manifest
      • 3.5 Permissions
      • 3.6 Summary
    • 4. Navigation
      • 4.1 Types of Navigation
      • 4.2 Implementation of the Bottom Navigation Bar
    • 5. Data and Persistent Storage
      • 5.1 Singleton Classes
      • 5.2 Shared Preferences
      • 5.3 Rooms
      • 5.4 Entities
      • 5.5 Data Access Objects
      • 5.6 Databases
    • 5.5 Concurrency
      • 5.5.1 Coroutines
      • 5.5.2 Implementation of Coroutines
      • 5.5.3 Coroutines with Networking Calls
    • 6. Networking and 3rd Party libraries
      • 6.1 HTTP Overview
      • 6.2 3rd Party Libraries
      • 6.3 JSON and Moshi
      • 6.4 Retrofit
      • 6.5 Summary
    • 7. MVVM Design Pattern
      • 7.1 Key Idea
      • 7.2 Implementation Ideas
    • 8. Flows
    • 9. The Art and Ontology of Software
    • 10. 🔥 Firebase
      • 10.1 Setting up Firebase
      • 10.2 Authentication
      • 10.3 Analytics
      • 10.4 Messaging
      • 10.5 Firestore
  • Additional Topics
    • Git and GitHub
    • Exporting to APK
  • Archive
    • Archived Native Android Textbook Pages
      • 1. Layouts and More Views
        • 1.1 File Structure and File Types
        • 1.2 Resource Files
        • 1.3 Button and Input Control
        • 1.4 ViewGroups
        • 1.5 Summary + A Note On Chapter 2 Topics
      • 2. RecyclerViews
        • 2.1 RecyclerViews
        • 2.2 RecyclerView Performance
        • 2.3 Implementation of a Recycler View
        • 2.4 Implementation with Input Controls
        • 2.5 Filtering RecyclerViews
        • 2.6 Recyclerview Demo
      • 3. ListViews and Searching
        • 3.1 ListView vs. RecyclerView
        • 3.2 ListView Performance
        • 3.3 Implementation of a ListView
        • 3.4 Searching in a List View
      • 4. Fragments
        • 4.1 What are Fragments?
        • 4.2 Lifecycle of a Fragment
        • 4.3 Integrating a Fragment into an Activity
        • 4.4 Sharing Data Between Fragments
        • 4.5 Fragment Slide Shows
      • 5. OkHttp
      • 6. Activity Lifecycle
      • 7. Implementation of Tab Layout
    • Fall 2024 Course Material
      • Lecture 1 & Exercise 1: Introduction to Android
      • Lecture 1.5: Beauty of Kotlin
      • Lecture 2 & HW 2: Modifiers, Lazylists and Reactive UI
      • Lecture 3 & HW 3: Animations, Intents and Manifest
      • Lecture 4 & HW 4: Coroutines & Navigation
      • Lecture 5 & HW 5: Persistent Storage, Networking, and JSON Parsing
      • Lecture 6 & HW 6: MVVM, Flows
      • Bonus Lectures & Bonus HW
      • Bonus Lecture: Industry Practice
    • Spring 2024 Course Material
      • Lecture 1 & Exercise 1: Introduction to Android
      • Lecture 4 & HW 4: LazyLists
      • Lecture 6 & HW 6: Networking, Data, and Persistent Storage
    • Spring 2020 Course Material
      • Week 1: Intro to the Editor
      • Week 2: Views and Layouts
      • Week 3: Intent and Manifest
      • Week 4: ListView and RecyclerView
      • Week 5: Fragments
      • Week 6: Networking
    • Spring 2021 Lecture & HW 8: Networking & 3rd Party APIs
    • HackOurCampus Workshop
Powered by GitBook
On this page
  • Preliminary Steps
  • Step 0: Importing the material design library:
  • Step 1: Creating Fragments or views
  • TabLayout with ViewPager
  • Step 1: Adding TabLayout and ViewPager2 to XML
  • Step 2: Wire up the fragments to ViewPager2
  • Step 3: Wiring ViewPager2 to TabLayout
  • TabLayout without ViewPagers

Was this helpful?

  1. Archive
  2. Archived Native Android Textbook Pages

7. Implementation of Tab Layout

The tab layout is often used for navigation systems that allow swiping between different screens (in conjunction with a ViewPager), and this can often be done as the first level of navigation or the second. Unlike the implementation for the bottom navigation bar, most of the code used to set up the tab layout belongs in the logic files rather than the layout XML.

Preliminary Steps

Step 0: Importing the material design library:

Same as the implementation for the bottom navigation bar, you'll need to add the material design library to build.gradle to use the tab layout.

build.gradle (Module: app)
implementation 'com.google.android.material:material:1.2.1'

Step 1: Creating Fragments or views

First, you'll want to create all the fragments that you'll need for the tab layout. You can do this easily by navigating to [Right click] > New > Fragment > Fragment (Blank). In our example, the fragment will contain a TextView with the fragment name inside:

FragmentA.kt
class FragmentA : Fragment() {
    private lateinit var textView: TextView

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val view = inflater.inflate(R.layout.fragment_a, container, false)
        textView = view.findViewById(R.id.textviewA)
        textView.text = "A"
        return view
    }

    companion object {
        @JvmStatic
        fun newInstance() = FragmentA()
    }
}

If you need a refresher on what Fragments are or what these methods mean, you can visit:

We'll also go ahead and create another Fragment in the same way as above and call it FragmentB.

TabLayout with ViewPager

Step 1: Adding TabLayout and ViewPager2 to XML

Next in the XML of our activity, we'll need to add the TabLayout and ViewPager2. The tab layout holds the different tabs and manages the swiping visual cue when the user switches screens. The view pager is the container that holds the view or fragment.

We can just add the two UI components like so, with TabLayout above ViewPager2:

activity_main.xml
<com.google.android.material.tabs.TabLayout
    android:id="@+id/tab_layout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="?android:attr/actionBarSize"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

<androidx.viewpager2.widget.ViewPager2
    android:id="@+id/view_pager"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight="1"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/tab_layout" />

Step 2: Wire up the fragments to ViewPager2

Inside of our activity in onCreate(), we'll just have to dictate how the position of the view pager affects the content inside:

MainActivity.kt
override fun onCreate(savedInstanceState: Bundle?) {
    viewPager = findViewById(R.id.view_pager)
    
    // create new fragment adapter for the view pager
    viewPager.adapter = object : FragmentStateAdapter(this) {
        override fun createFragment(position: Int): Fragment {

            // return the correct fragment based on the position 
            // of the view pager
            return when (position) {
                0 -> FragmentA.newInstance()
                1 -> FragmentB.newInstance()
                else -> FragmentA.newInstance() // else is required, this should never happen as long
                // as getItemCount accurately reflects the number of fragments you have!
            }
        }
    
        // get the number of pages in the view pager
        override fun getItemCount(): Int {
            return 2
        }
    }
}

Setting up the adapter for the view pager just requires us to override two function createFragment(...) and getItemCount(), and as you can see above, it's not too difficult to set up.

Step 3: Wiring ViewPager2 to TabLayout

Finally, we just have to add functionality to the tabs in TabLayout so that the view pager knows which page to switch to, and all of this can be done through the TabLayoutMediator. This will also be the method that handles the naming of the tabs.

MainActivity.kt
tabLayout = findViewById(R.id.tab_layout)
TabLayoutMediator(tabLayout, viewPager) { tab, position ->
    when (position) {
        0 -> tab.text = "Fragment A"
        1 -> tab.text = "Fragment B"
    }
}.attach()

At this point, if we run the emulator, we should see an application that looks something like this, and the user can swipe between the different screens, where each screen is a different fragment.

A unique property of ViewPagers is that it preloads a certain number of pages to the left and right of your currentPage when the adapter is first created in the flow of your app which makes it hard to dynamically respond to changes!

ex: viewPager2.adapter.notifyItemChanged(0)

TabLayout without ViewPagers

You can also manually handle the transitions between the clicking of tabs yourself which may offer more flexibility!

For example:

val tabLayout = findViewById<TabLayout>(R.id.tab_layout)
tabLayout.addTab(tabLayout.newTab().setText("Home"))
tabLayout.addTab(tabLayout.newTab().setText("Profile"))

You can then listen in to changes in the TabLayout programatically:

tabLayout.addOnTabSelectedListener(object : OnTabSelectedListener {
    override fun onTabSelected(tab: TabLayout.Tab) {
        when(tab.position) {
            // Carry out various Fragment transactions (replacing, swapping, etc)
            // on the fragment container in your activity (see section 6.3)
            0 -> ...
            1 -> ...
        }
    }

    override fun onTabUnselected(tab: TabLayout.Tab) {}
    override fun onTabReselected(tab: TabLayout.Tab) {}
})
Previous6. Activity LifecycleNextFall 2024 Course Material

Last updated 8 months ago

Was this helpful?

Screen slides are transitions between one entire screen to another and are common with UIs like setup wizards or slideshows. The allows us to do screen slides easily with fragments and can animate screen slides automatically. ViewPagers integrate well with TabLayouts in the sense where if you slide the ViewPager, the tabs will change to correspond! There was a brief introduction to ViewPagers without TabLayouts in!

If you are modifying other fragments in your ViewPager or trying to share data in between using techniques from 4.4 Sharing Data Between Fragments, you MUST call on after to refresh the stale data in your fragment from when it was preloaded. NotifyItemChanged takes in the index of the Fragment being refreshed.

Population of the tabs to display is done through instances. You create tabs via . From there you can change the tab's label or icon via and respectively. To display the tab, you need to add it to the layout via one of the methods.

4.1 What are Fragments?
ViewPager
section 6.4
notifyItemChanged
TabLayout.Tab
newTab()
TabLayout.Tab.setText(int)
TabLayout.Tab.setIcon(int)
addTab(Tab)
Emulator