SoFunction
Updated on 2025-04-10

Android uses ViewPager to realize three fragment switching

1. Basic usage of ViewPager

Overview

ViewPager is a class in the Android extension v4 package. This class allows us to switch the current view left and right. Let’s first talk about several related knowledge points of ViewPager:

  1. The ViewPager class directly inherits the ViewGroup class, so it is a container class that can add other view classes.
  2. The ViewPager class requires a PagerAdapter adapter class to provide it with data (this is the same as ListView requires a data adapter Adater)
  3. ViewPager is often used with Fragment, and the official also provides special FragmentPagerAdapter and FragmentStatePagerAdapter classes for use by ViewPager in Fragment.

Use Cases

We just need to add the following code to the xml layout file:

activity_main.xml:

<RelativeLayout xmlns:andro
  xmlns:tools="/tools"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  tools:context=".MainActivity">

  <.
    android:
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">
  </.>

</RelativeLayout>

(as a sub-layout of ViewPager):

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:andro
  android:orientation="vertical" android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:background="@color/colorAccent"
  >

  <TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Tab1"
    />

</LinearLayout>

Then here we first create 4 interfaces to be displayed in the ViewPager, the code is as follows:

ArrayList&lt;View&gt; viewContainter = new ArrayList&lt;View&gt;();
View view1 = (this).inflate(.tab1, null);
View view2 = (this).inflate(.tab2, null);
View view3 = (this).inflate(.tab3, null);
View view4 = (this).inflate(.tab4, null);
//viewContainer Add view(view1);
(view2);
(view3);
(view4);

After we have data, we need to create a data adapter. We create a data adapter. MyPagerAdapter inherits from PagerAdapter. In PagerAdapter, we must rewrite the following methods:

int getCount()
getCount(): Returns the number of VIews that can be swiped

void destroyItem(ViewGroup container, int position,Object object)
Delete View at the specified location from the current container

Object instantiateItem(ViewGroup container, int position)
Add the current view to the container and return the current View view

boolean isViewFromObject(View arg0, Object arg1)
This function is used to determine whether the object returned by the instantiateItem(ViewGroup, int) function and a page view represent the same view. The official suggests that you can directly return arg0 == arg1.

Below we give the complete code of MyPagerAdapters:

/**
 * ViewPager's data adapter
 */
class MyPagerAdapters extends PagerAdapter{
  //Return the number of VIews that can be swiped  @Override
  public int getCount() {
    return ();
  }
  //Destroy the current component during sliding switch  @Override
  public void destroyItem(ViewGroup container, int position,
              Object object) {
    ((ViewPager) container).removeView((position));
  }
  //Add the current view to the container and return the current View view  @Override
  public Object instantiateItem(ViewGroup container, int position) {
    ((ViewPager) container).addView((position));
    return (position);
  }

  @Override
  public boolean isViewFromObject(View arg0, Object arg1) {
    return arg0 == arg1;
  }

Finally, we just need to set the MyPagerAdapters adapter to the ViewPager:

pager = (ViewPager) ();
(new MyPagerAdapters());

The complete code of MainActivity is as follows:

package ;

import ;
import ;
import ;
import .;
import .;
import .;
import ;
import ;
import ;

import ;

public class MainActivity extends Activity {

  ViewPager pager = null;
  PagerTabStrip tabStrip = null;
  ArrayList&lt;View&gt; viewContainter = new ArrayList&lt;View&gt;();

  @SuppressLint("ResourceAsColor")
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    (savedInstanceState);
    setContentView(.activity_main);

    pager = (ViewPager) ();

    View view1 = (this).inflate(.tab1, null);
    View view2 = (this).inflate(.tab2, null);
    View view3 = (this).inflate(.tab3, null);
    View view4 = (this).inflate(.tab4, null);
    //viewpager starts adding view    (view1);
    (view2);
    (view3);
    (view4);
    //Set Adapter    (new MyPagerAdapters());

  }

  /**
   * ViewPager's data adapter
   */
  class MyPagerAdapters extends PagerAdapter{
    //Return the number of VIews that can be swiped    @Override
    public int getCount() {
      return ();
    }
    //Destroy the current component during sliding switch    @Override
    public void destroyItem(ViewGroup container, int position,
                Object object) {
      ((ViewPager) container).removeView((position));
    }
    //Add the current view to the container and return the current View view    @Override
    public Object instantiateItem(ViewGroup container, int position) {
      ((ViewPager) container).addView((position));
      return (position);
    }

    @Override
    public boolean isViewFromObject(View arg0, Object arg1) {
      return arg0 == arg1;
    }
  }
}

At this point, the simplest way to use ViewPager has been introduced.

Classes and PagerTabStrip classes

When we write ViewPager application, we will also use two component classes, namely the PagerTitleStrip class and the PagerTabStrip class. The PagerTitleStrip class is directly inherited from the ViewGroup class and is used to set the title of each page. The PagerTabStrip class inherits the PagerTitleStrip class to control the bar style or title style when selecting Tab. These two classes are also container classes. However, there is one thing we need to pay special attention to. When defining the layout of XML, these two classes must be subtitles of the ViewPager tag, otherwise an error will occur. Since the PagerTabStrip class inherits the PagerTitleStrip class, PagerTabStrip expands the PagerTitleStrip class function, so here we only demonstrate the usage of PagerTabStrip.

First we add the PagerTabStrip control to the activity_main.xml file:

<RelativeLayout xmlns:andro
  xmlns:tools="/tools"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  tools:context=".MainActivity">

  <.
    android:
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">

    <.
      android:
      android:layout_width="wrap_content"
      android:layout_height="50dip"
      android:gravity="center" />

  </.>

</RelativeLayout>

Then we create the title data in the file:

ArrayList&lt;String&gt; titleContainer = new ArrayList&lt;String&gt;();
//Tag Item
("Today's Headlines");

("Today's Hot Topic");

("Today's Finance");

("Today's Military");

To add a title to each tab, we must rewrite the getPageTitle method in the PagerAdapter class, and then obtain the corresponding title from the collection data according to the position position. This method is implemented as follows:

@Override
public CharSequence getPageTitle(int position) {
  return (position);
}

Next, we will change the style of the lower horizontal line indicating the line of each Tab through the PagerTabStrip control. The code is as follows:

 tabStrip = (PagerTabStrip) ();
//Cancel the long horizontal line below the tab(false);
//Set the background color of the tab();
//Set the underline color of the current tab tab();
(400);

At this point, the title and indicator are set up. Let’s give the revised MainActivity code:

package ;

import ;
import ;
import ;
import .;
import .;
import .;
import ;
import ;
import ;

import ;

public class MainActivity extends Activity {

  ViewPager pager = null;
  PagerTabStrip tabStrip = null;
  ArrayList&lt;View&gt; viewContainter = new ArrayList&lt;View&gt;();
  ArrayList&lt;String&gt; titleContainer = new ArrayList&lt;String&gt;();

  @SuppressLint("ResourceAsColor")
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    (savedInstanceState);
    setContentView(.activity_main);

    pager = (ViewPager) ();
    tabStrip = (PagerTabStrip) ();
    //Cancel the long horizontal line below the tab    (false);
    //Set the background color of the tab    ();
    //Set the underline color of the current tab tab    ();
    (400);

    View view1 = (this).inflate(.tab1, null);
    View view2 = (this).inflate(.tab2, null);
    View view3 = (this).inflate(.tab3, null);
    View view4 = (this).inflate(.tab4, null);
    //viewpager starts adding view    (view1);
    (view2);
    (view3);
    (view4);
    //Tag Item    ("Today's Headlines");
    ("Today's Hot Topic");
    ("Today's Finance");
    ("Today's Military");

    (new MyPagerAdapters());

  }

  /**
    * ViewPager's data adapter
    */
  class MyPagerAdapters extends PagerAdapter{
    //Return the number of VIews that can be swiped    @Override
    public int getCount() {
      return ();
    }
    //Destroy the current component during sliding switch    @Override
    public void destroyItem(ViewGroup container, int position,
                Object object) {
      ((ViewPager) container).removeView((position));
    }
    //Add the current view to the container and return the current View view    @Override
    public Object instantiateItem(ViewGroup container, int position) {
      ((ViewPager) container).addView((position));
      return (position);
    }

    @Override
    public boolean isViewFromObject(View arg0, Object arg1) {
      return arg0 == arg1;
    }

    @Override
    public CharSequence getPageTitle(int position) {
      return (position);
    }
  }
}

In fact, PagerTabStrip and PagerTitleStrip are rarely used in our development, because the title bar they implement is very poor, and we cannot specify that a page displays one at a time, or all of them are displayed, and the title also slides along with the interface. Therefore, it is not recommended to use it in actual applications. We are more about customizing indicators, so the effect will be better. Well, here we end this article.

Basic usage of Fragment+ViewPager

With FragmentStatePagerAdapter

When ViewPager is used in combination with Fragment, the data adapter we need to use is no longer PagerAdapter, but also the official data adapter provided by FragmentPagerAdapter and FragmentStatePagerAdapter data adapter. Let's first talk about the usage methods and their main differences between these two FragmentPagerAdapter and FragmentStatePagerAdapter.

FragmentPagerAdapter

FragmentPagerAdapter inherits from PagerAdapter. Compared to the general PagerAdapter, this class focuses more on the situation where each page is a Fragment. Each generated fragment in this class will be saved in memory. Although invisible views are sometimes destroyed, all fragments visited by the user will be saved in memory. Therefore, fragment instances will save a large number of various states, which causes a large memory overhead. Therefore, FragmentPagerAdapter is more suitable for those relatively static pages and relatively small application scenarios, such as mainstream main interfaces; if you need to deal with many pages, and the data is dynamic and occupies a lot of memory, you should use FragmentStatePagerAdapter. Corresponding to implementing FragmentPagerAdapter, we only need to override the two methods getCount() and getItem(), so it is more convenient than inheriting from PagerAdapter. Next, let's take a look at how to implement FragmentPagerAdapter with code

 class MyFragmentAdapter extends FragmentPagerAdapter{

    List&lt;Fragment&gt; list;

    public MyFragmentAdapter(FragmentManager fm,List&lt;Fragment&gt; list) {
      super(fm);
      =list;
    }

    /**
      * Return the fragment that needs to be displayed
      * @param position
      * @return
      */
    @Override
    public Fragment getItem(int position) {
      return (position);
    }

    /**
      * Return the number of fangments to be displayed
      * @return
      */
    @Override
    public int getCount() {
      return ();
    }
}

The code is quite simple, we can simply use the following two functions

getItem(int position)
This function is actually a fragment interface that needs to be displayed according to the subscript position. This method is called in the PagerAdapter#instantiateItem() method. Just look at the source code of the FragmentPagerAdapter will be clear.

getCount()
This function is simpler and returns the total number of fragments to be displayed.

At this point, we have finished introducing the FragmentPagerAdapter. Let’s continue to take a look at the FragmentStatePagerAdapter class.

FragmentStatePagerAdapter

FragmentStatePagerAdapter Like FragmentPagerAdapter, it is an inherited child PagerAdapter. But their difference is that the meaning of ‘State’ in their class name is the same. The implementation of the PagerAdapter will only retain the current page. When the page leaves sight, it will be eliminated and its resources will be released; and when the page needs to be displayed, a new page will be generated. The biggest benefit of this implementation is that when you have a large number of pages, you don't have to take up a lot of memory in memory. When we implement FragmentStatePagerAdapter, we only need to override the two methods getCount() and getItem(), and the meaning of the method is the same as that of FragmentPagerAdapter. Let’s take a look at the implementation case, and in fact, it’s just a change to the inheritance class.

class MyFragmentStateAdapter extends FragmentStatePagerAdapter{

    List&lt;Fragment&gt; list;

    public MyFragmentStateAdapter(FragmentManager fm,List&lt;Fragment&gt; list) {
      super(fm);
      =list;
    }

    /**
      * Return the fragment that needs to be displayed
      * @param position
      * @return
      */
    @Override
    public Fragment getItem(int position) {
      return (position);
    }

    /**
      * Return the number of fangments to be displayed
      * @return
      */
    @Override
    public int getCount() {
      return ();
    }
  }

From a code perspective, the inheritance class has been changed, and nothing else has changed. Finally, let’s implement a simple example;

Let's first write the required Fragment layout. As follows:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:andro
  android:orientation="vertical" android:layout_width="match_parent"
  android:layout_height="match_parent">

  <TextView
    android:
    android:textSize="20dp"
    android:textColor="@color/white"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />
</LinearLayout>

The code is as follows:

package ;

package ;

import ;
import ;
import .;
import ;
import ;
import ;
import ;

/**
 * Created by zejian
 * Time 16/8/7.
 * Description:
 */
public class FragmentView extends Fragment {

  private Bundle arg;
  @Override
  public void onCreate(@Nullable Bundle savedInstanceState) {
    (savedInstanceState);
    arg=getArguments();
  }

  @Nullable
  @Override
  public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    View view= (,null);
    TextView tv= (TextView) ();
    int page=("pager_num");

    if (page==1){
      ();
    }else if(page==2){
      ();
    }else if(page==3){
      ();
    }else if(page==4){
      ();
    }

    (("Title"));
    return view;
  }


  public static FragmentView newInstance(Bundle args) {
    FragmentView fragment = new FragmentView();
    (args);
    return fragment;
  }

}

The code of the Fragment is also very fresh. We use the passed parameters to judge the background color of each fragment, set the title name, and finally return the view we need to display. Let's take a look at the layout file of the activity

activity_vp_fg.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:andro
  android:orientation="vertical" android:layout_width="match_parent"
  android:layout_height="match_parent">

  <.
    android:
    android:layout_width="match_parent"
    android:layout_height="match_parent">

  </.>
</LinearLayout>

VP_FG_Activity.java

package ;

import ;
import ;
import .;
import .;
import .;
import .;
import .;
import .;

import ;
import ;

/**
 * Created by zejian
 * Time 16/8/7.
 * Description:
 */
public class VP_FG_Activity extends FragmentActivity {

  private ViewPager viewPager;

  @Override
  protected void onCreate(@Nullable Bundle savedInstanceState) {
    (savedInstanceState);
    setContentView(.activity_vp_fg);
    viewPager= (ViewPager) findViewById();
    initData();
  }

  public void initData(){

    List&lt;Fragment&gt; list=new ArrayList&lt;&gt;();

    Bundle bundle1=new Bundle();
    ("Title","First Fragment");
    ("pager_num",1);
    Fragment fg1=(bundle1);

    Bundle bundle2=new Bundle();
    ("Title","Second Fragment");
    ("pager_num",2);
    Fragment fg2=(bundle2);

    Bundle bundle3=new Bundle();
    ("Title","Third Fragment");
    ("pager_num",3);
    Fragment fg3=(bundle3);

    Bundle bundle4=new Bundle();
    ("Title","Fourth Fragment");
    ("pager_num",4);
    Fragment fg4=(bundle4);

    (fg1);
    (fg2);
    (fg3);
    (fg4);

    (new MyFragmentAdapter(getSupportFragmentManager(),list));

  }

  class MyFragmentAdapter extends FragmentPagerAdapter{

    List&lt;Fragment&gt; list;

    public MyFragmentAdapter(FragmentManager fm,List&lt;Fragment&gt; list) {
      super(fm);
      =list;
    }

    /**
      * Return the fragment that needs to be displayed
      * @param position
      * @return
      */
    @Override
    public Fragment getItem(int position) {
      return (position);
    }

    /**
      * Return the number of fangments to be displayed
      * @return
      */
    @Override
    public int getCount() {
      return ();
    }
  }
  class MyFragmentStateAdapter extends FragmentStatePagerAdapter{

    List&lt;Fragment&gt; list;

    public MyFragmentStateAdapter(FragmentManager fm,List&lt;Fragment&gt; list) {
      super(fm);
      =list;
    }

    /**
      * Return the fragment that needs to be displayed
      * @param position
      * @return
      */
    @Override
    public Fragment getItem(int position) {
      return (position);
    }

    /**
      * Return the number of fangments to be displayed
      * @return
      */
    @Override
    public int getCount() {
      return ();
    }
  }
}

In Activity, we use the following code to initialize the data required by ViewPager

List&lt;Fragment&gt; list=new ArrayList&lt;&gt;();

Bundle bundle1=new Bundle();
("Title","First Fragment");
("pager_num",1);
Fragment fg1=(bundle1);

Bundle bundle2=new Bundle();
("Title","Second Fragment");
("pager_num",2);
Fragment fg2=(bundle2);

Bundle bundle3=new Bundle();
("Title","Third Fragment");
("pager_num",3);
Fragment fg3=(bundle3);

Bundle bundle4=new Bundle();
("Title","Fourth Fragment");
("pager_num",4);
Fragment fg4=(bundle4);

(fg1);
(fg2);
(fg3);
(fg4);

(new MyFragmentAdapter(getSupportFragmentManager(),list));

Finally, set the data time adapter MyFragmentAdapter to the ViewPager, so that the data is filled. It is important to note here that Activity inherits from FragmentActivity, and only FragmentActivity can embed fragment pages, and ordinary Activity cannot.

After running the program, we have a clear understanding of how to use Fragment+ViewPager. This article comes to an end. I hope it will be helpful to everyone's learning and I hope everyone will support me more.