ViewPager Using Fragments in Android with Example
ViewPager is a layout manager that allows the user to flip left and right through pages of data. It is mostly found in apps like Youtube, Snapchat where the user shifts right – left to switch to a screen. Instead of using activities fragments are used. It is also used to guide the user through the app when the user launches the app for the first time.
ViewPager Using Fragments in Android
Steps for implementing viewpager:
- Adding the ViewPager widget to the XML layout (usually the main_layout).
- Creating an Adapter by extending the FragmentPagerAdapter or FragmentStatePagerAdapter class.
An adapter populates the pages inside the Viewpager. PagerAdapter is the base class which is extended by FragmentPagerAdapter and FragmentStatePagerAdapter. Let’s see a quick difference between the two classes.
Difference between FragmentPagerAdapter and FragmentStatePagerAdapter:
- FragmentStatePagerAdapter: Keeps in memory only the current fragment displayed on the screen. This is memory efficient and should be used in applications with dynamic fragments. (where the number of fragments is not fixed.).
- FragmentPagerAdapter: This adapter should be used when the number of fragments is fixed. An application that has 3 tabs which won’t change during the runtime of the application. This tutorial will be using FragmentPagerAdapter.
Following is the structure of the ViewPagerAdapter Class:
Java
import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentPagerAdapter; import java.util.ArrayList; import java.util.List; public class ViewPagerAdapter extends FragmentPagerAdapter { private final List<Fragment> fragments = new ArrayList<>(); private final List<String> fragmentTitle = new ArrayList<>(); public ViewPagerAdapter( @NonNull FragmentManager fm) { super (fm); } public void add(Fragment fragment, String title) { fragments.add(fragment); fragmentTitle.add(title); } @NonNull @Override public Fragment getItem( int position) { return fragments.get(position); } @Override public int getCount() { return fragments.size(); } @Nullable @Override public CharSequence getPageTitle( int position) { return fragmentTitle.get(position); } } |
Method Description:
- getCount(): This method returns the number of fragments to display. (Required to Override)
- getItem(int pos): Returns the fragment at the pos index. (Required to override)
- ViewPagerAdapter(@NonNull FragmentManager FM): (required) The ViewPager Adapter needs to have a parameterized constructor that accepts the FragmentManager instance. Which is responsible for managing the fragments. A FragmentManager manages Fragments in Android, specifically, it handles transactions between fragments. A transaction is a way to add, replace, or remove fragments.
- getPageTitle(int pos): (optional) Similar to getItem() this methods returns the title of the page at index pos.
- add(Fragment fragment, String title): This method is responsible for populating the fragments and fragmentTitle lists. which hold the fragments and titles respectively.
Example
A sample GIF is given below to get an idea about what we are going to do in this article. Note that we are going to implement this project using the Java language.
Step by Step Implementation
Step 1: Create a New Project
To create a new project in Android Studio please refer to How to Create/Start a New Project in Android Studio. Note that select Java as the programming language. Initially, the project directory should look like this.
Step 2: Working with the activity_main.xml file
The three widgets AppBarLayout used to host the TabLayout which is responsible for displaying the page titles. ViewPager layout which will house the different fragments. The below Image explains the important parameters to set to get the app working as intended.
In the TabLayout we need to add the tabmode = “fixed” parameter which tells the android system that will have a fixed number of tabs in our application. Add the following code to the “activity_main.xml” file.
XML
<? 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/appbar" android:layout_width = "match_parent" android:layout_height = "wrap_content" > < com.google.android.material.tabs.TabLayout android:id = "@+id/tab_layout" android:layout_width = "match_parent" android:layout_height = "match_parent" app:tabGravity = "fill" app:tabMode = "fixed" /> </ com.google.android.material.appbar.AppBarLayout > < androidx.viewpager.widget.ViewPager android:id = "@+id/viewpager" android:layout_width = "match_parent" android:layout_height = "match_parent" app:layout_behavior = "@string/appbar_scrolling_view_behavior" /> </ androidx.coordinatorlayout.widget.CoordinatorLayout > |
Step 3: Create Fragments
Now we need to design out pages that are fragmented. For this tutorial, we will be using three Pages (fragments). Add three blank fragments to the project. The project Structure should look like this.
Below is the code for the Page1.java, Page2.java, and Page3.java file respectively.
Java
import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; public class Page1 extends Fragment { public Page1() { // required empty public constructor. } @Override public void onCreate( @Nullable Bundle savedInstanceState) { super .onCreate(savedInstanceState); } @Nullable @Override public View onCreateView( @NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment_page1, container, false ); } } |
Java
import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; public class Page2 extends Fragment { public Page2() { // required empty public constructor. } @Override public void onCreate( @Nullable Bundle savedInstanceState) { super .onCreate(savedInstanceState); } @Nullable @Override public View onCreateView( @NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment_page2, container, false ); } } |
Java
import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; public class Page3 extends Fragment { public Page3() { // required empty public constructor. } @Override public void onCreate( @Nullable Bundle savedInstanceState) { super .onCreate(savedInstanceState); } @Nullable @Override public View onCreateView( @NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { return inflater.inflate(R.layout.fragment_page3, container, false ); } } |
Method Description:
- Page1(): Default Constructure.
- onCreateView( onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState): This method is responsible for inflating (parsing) the respective XML file and return the view which is added to the ViewPager adapter.
- onCreate(Bundle SaveInstanceState): This methods is similar to activities OnCreate() method.
Designing the Page XML Files. All the fragments XML layouts have the same designs. We have a TextView at the center displaying the name of the respective page, the root container used here is FrameLayout whose background is set to #0F9D58
Below is the code for the fragment_page1.xml file:
Code:
XML
<? xml version = "1.0" encoding = "utf-8" ?> < FrameLayout 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" android:background = "#0F9D58" tools:context = ".Page1" > <!-- TODO: Update blank fragment layout --> < TextView android:layout_width = "match_parent" android:layout_height = "match_parent" android:gravity = "center" android:text = "Page 1" android:textColor = "@color/white" android:textSize = "60sp" android:textStyle = "bold" /> </ FrameLayout > |
Below is the code for the fragment_page2.xml file:
Code:
XML
<? xml version = "1.0" encoding = "utf-8" ?> < FrameLayout 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" android:background = "#0F9D58" tools:context = ".Page2" > <!-- TODO: Update blank fragment layout --> < TextView android:layout_width = "match_parent" android:layout_height = "match_parent" android:gravity = "center" android:text = "Page 2" android:textColor = "@color/white" android:textSize = "60sp" android:textStyle = "bold" /> </ FrameLayout > |
Below is the code for the fragment_page3.xml file:
Code:
XML
<? xml version = "1.0" encoding = "utf-8" ?> < FrameLayout 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" android:background = "#0F9D58" tools:context = ".Page3" > <!-- TODO: Update blank fragment layout --> < TextView android:layout_width = "match_parent" android:layout_height = "match_parent" android:gravity = "center" android:text = "Page 3" android:textColor = "@color/white" android:textSize = "60sp" android:textStyle = "bold" /> </ FrameLayout > |
Step 4: Creating the ViewPager Adapter
Add a java class named ViewPagerAdapter to the project structure. The project structure would look like this.
Below is the code for the ViewPagerAdapter.java file:
Java
import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentPagerAdapter; import java.util.ArrayList; import java.util.List; public class ViewPagerAdapter extends FragmentPagerAdapter { private final List<Fragment> fragments = new ArrayList<>(); private final List<String> fragmentTitle = new ArrayList<>(); public ViewPagerAdapter( @NonNull FragmentManager fm) { super (fm); } public void add(Fragment fragment, String title) { fragments.add(fragment); fragmentTitle.add(title); } @NonNull @Override public Fragment getItem( int position) { return fragments.get(position); } @Override public int getCount() { return fragments.size(); } @Nullable @Override public CharSequence getPageTitle( int position) { return fragmentTitle.get(position); } } |
Step 5: Working with the MainActivity.java file
In the MainActivity, we need to perform the following steps.
- Initialize the ViewPager, TabLayout, and the Adapter.
- Add the Pages (fragments ) along with the titles
- Link the TabLayout to the Viewpager using the setupWithiewPager method.
Syntax:TabLayout.setupWithiewPager(ViewPager pager).
Description: The tablayout with the viewpager. The titles of each pager now appears on the tablayout. The user can also navigate through the fragments by clicking on the tabs.
Parameter:
Viewpager: Used to display the fragments.
Below is the code for the MainActivity.java file. Comments are added inside the code to understand the code in more detail.
Java
import android.os.Bundle; import androidx.appcompat.app.AppCompatActivity; import androidx.viewpager.widget.ViewPager; import com.google.android.material.tabs.TabLayout; public class MainActivity extends AppCompatActivity { private ViewPagerAdapter viewPagerAdapter; private ViewPager viewPager; private TabLayout tabLayout; @Override protected void onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_main); viewPager = findViewById(R.id.viewpager); // setting up the adapter viewPagerAdapter = new ViewPagerAdapter(getSupportFragmentManager()); // add the fragments viewPagerAdapter.add( new Page1(), "Page 1" ); viewPagerAdapter.add( new Page2(), "Page 2" ); viewPagerAdapter.add( new Page3(), "Page 3" ); // Set the adapter viewPager.setAdapter(viewPagerAdapter); // The Page (fragment) titles will be displayed in the // tabLayout hence we need to set the page viewer // we use the setupWithViewPager(). tabLayout = findViewById(R.id.tab_layout); tabLayout.setupWithViewPager(viewPager); } } |
Output:
Find the code in the following GitHub repo: https://github.com/evilc3/ViewPager
Contact Us