anndroid uses ViewPager to implement three fragment switches

  • 2021-08-31 09:16:42
  • OfStack

1. Basic usage of ViewPager

1. ViewPager overview

ViewPager is a class in the android extension package v4, which allows us to switch the current view from side to side. Let's talk about some related knowledge points of ViewPager first:

The ViewPager class inherits directly from the ViewGroup class, so it is a container class, and other view classes can be added The ViewPager class requires an PagerAdapter adapter class to provide it with data. (This requires the data adapter Adater just like ListView1.) ViewPager is often used with Fragment1, and the official also provides special FragmentPagerAdapter and FragmentStatePagerAdapter classes for ViewPager in Fragment

2. ViewPager use case

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

activity_main.xml:


<RelativeLayout 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"
  tools:context=".MainActivity">

  <android.support.v4.view.ViewPager
    android:id="@+id/viewpager"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">
  </android.support.v4.view.ViewPager>

</RelativeLayout>

tab. xml (as a sublayout of ViewPager):


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  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 we first create four interfaces to be displayed in ViewPager. The code is as follows:


ArrayList<View> viewContainter = new ArrayList<View>();
View view1 = LayoutInflater.from(this).inflate(R.layout.tab1, null);
View view2 = LayoutInflater.from(this).inflate(R.layout.tab2, null);
View view3 = LayoutInflater.from(this).inflate(R.layout.tab3, null);
View view4 = LayoutInflater.from(this).inflate(R.layout.tab4, null);
//viewContainter Add view
viewContainter.add(view1);
viewContainter.add(view2);
viewContainter.add(view3);
viewContainter.add(view4);

When we have the data, we will create a data adapter. We create a data adapter MyPagerAdapter inherited from PagerAdapter. In PagerAdapter, we must override the following methods:

int getCount()
getCount (): Returns the number of VIew that can slide

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

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

boolean isViewFromObject(View arg0, Object arg1)
This function is used to judge whether Object and one page view returned by instantiateItem (ViewGroup, int) functions represent the same view. It is officially recommended to return arg0 = = arg1 directly.

Below we give the complete code of MyPagerAdapters:


/**
*  ViewPager Data adapter of 
*/
class MyPagerAdapters extends PagerAdapter{
  // Returns a slidable VIew The number of 
  @Override
  public int getCount() {
    return viewContainter.size();
  }
  // Destroy the current component when sliding toggle 
  @Override
  public void destroyItem(ViewGroup container, int position,
              Object object) {
    ((ViewPager) container).removeView(viewContainter.get(position));
  }
  // Add the current view to the container And returns the current View View 
  @Override
  public Object instantiateItem(ViewGroup container, int position) {
    ((ViewPager) container).addView(viewContainter.get(position));
    return viewContainter.get(position);
  }

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

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


pager = (ViewPager) this.findViewById(R.id.viewpager);
pager.setAdapter(new MyPagerAdapters());

The complete code for MainActivity is as follows:


package com.zejian.viewpager;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.Bundle;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.PagerTabStrip;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import java.util.ArrayList;

public class MainActivity extends Activity {

  ViewPager pager = null;
  PagerTabStrip tabStrip = null;
  ArrayList<View> viewContainter = new ArrayList<View>();

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

    pager = (ViewPager) this.findViewById(R.id.viewpager);

    View view1 = LayoutInflater.from(this).inflate(R.layout.tab1, null);
    View view2 = LayoutInflater.from(this).inflate(R.layout.tab2, null);
    View view3 = LayoutInflater.from(this).inflate(R.layout.tab3, null);
    View view4 = LayoutInflater.from(this).inflate(R.layout.tab4, null);
    //viewpager Start adding view
    viewContainter.add(view1);
    viewContainter.add(view2);
    viewContainter.add(view3);
    viewContainter.add(view4);
    // Settings Adapter
    pager.setAdapter(new MyPagerAdapters());

  }

  /**
  *  ViewPager Data adapter of 
  */
  class MyPagerAdapters extends PagerAdapter{
    // Returns a slidable VIew The number of 
    @Override
    public int getCount() {
      return viewContainter.size();
    }
    // Destroy the current component when sliding toggle 
    @Override
    public void destroyItem(ViewGroup container, int position,
                Object object) {
      ((ViewPager) container).removeView(viewContainter.get(position));
    }
    // Add the current view to the container And returns the current View View 
    @Override
    public Object instantiateItem(ViewGroup container, int position) {
      ((ViewPager) container).addView(viewContainter.get(position));
      return viewContainter.get(position);
    }

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

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

3. Class PagerTitleStrip and Class PagerTabStrip

When we write the application of ViewPager, we will also use two component classes, namely PagerTitleStrip class and PagerTabStrip class. PagerTitleStrip class directly inherits from ViewGroup class for setting the title of each page, while PagerTabStrip class inherits PagerTitleStrip class for controlling the indicator bar style or title style when Tab is selected. These two classes are also container classes. However, we should pay special attention to one point. When defining layout of XML, these two classes must be child tags of ViewPager tag, otherwise an error will occur. Since the PagerTabStrip class inherits the PagerTitleStrip class, PagerTabStrip extends the functionality of the PagerTitleStrip class, so here we will only demonstrate PagerTabStrip usage.

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


<RelativeLayout 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"
  tools:context=".MainActivity">

  <android.support.v4.view.ViewPager
    android:id="@+id/viewpager"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">

    <android.support.v4.view.PagerTabStrip
      android:id="@+id/tabstrip"
      android:layout_width="wrap_content"
      android:layout_height="50dip"
      android:gravity="center" />

  </android.support.v4.view.ViewPager>

</RelativeLayout>

We then create header data in the MainActivity. java file:


ArrayList<String> titleContainer = new ArrayList<String>();
// Tab item 

titleContainer.add(" Today's headlines ");

titleContainer.add(" Hot spot today ");

titleContainer.add(" Finance and Economics Today ");

titleContainer.add(" Military today ");

To add a title to each tab, we must override the getPageTitle method in the PagerAdapter class, and then get the corresponding title from the collection data according to the position position and return it. The method is implemented as follows:


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

Next, we change the style of the underline indicator line of each Tab through the PagerTabStrip control. The code is as follows:


 tabStrip = (PagerTabStrip) this.findViewById(R.id.tabstrip);
// Cancel tab Long horizontal line below 
tabStrip.setDrawFullUnderline(false);
// Settings tab Background color of 
tabStrip.setBackgroundResource(R.color.bg);
// Sets the current tab Underline color of tab 
tabStrip.setTabIndicatorColorResource(R.color.red);
tabStrip.setTextSpacing(400);

Now that the header and indicator are set up, we give the revised MainActivity code:


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  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>
0

In fact, we rarely use PagerTabStrip and PagerTitleStrip in our development, because their title bar effect is very bad, and we can't specify one page to display one at a time, or all of them, and the title also slides along with the interface. Therefore, it is not recommended to use it in practical application. We're more about customizing the indicator, so the effect will be better. OK, here, let's go to paragraph 1 of this article.

Basic Usage of Fragment+ViewPager

1. FragmentPagerAdapter and FragmentStatePagerAdapter

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

FragmentPagerAdapter

FragmentPagerAdapter inherits from PagerAdapter. Compared with the general PagerAdapter, this class is more focused on the case where every 1 page is Fragment. Every Fragment generated in this class is stored in memory, and although invisible views are sometimes destroyed, all fragment accessed by the user are stored in memory, so the fragment instance will store a large number of various states, which causes a large memory overhead. Therefore, FragmentPagerAdapter is more suitable for those relatively static pages, and the number of application scenarios is relatively small, such as the mainstream main interface; FragmentStatePagerAdapter should be used if you need to deal with situations where there are many pages and data is dynamic and takes up a lot of memory. To implement FragmentPagerAdapter, we only need to override getCount () and getItem (), so it is more convenient than inheriting from PagerAdapter. Next, let's look at how to implement FragmentPagerAdapter in code


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  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>
1

The code is quite simple. We will simplify the following two functions here

getItem(int position)
This function is actually according to the subscript position needs to show the fragment interface, this method is in PagerAdapter # instantiateItem () method is called, you just look at 1 FragmentPagerAdapter source code is clear.

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

Now that we've covered FragmentPagerAdapter, let's move on to the FragmentStatePagerAdapter class.

FragmentStatePagerAdapter

FragmentStatePagerAdapter and FragmentPagerAdapter 1 are inheritors of PagerAdapter. However, the difference between them lies in the meaning indicated by 'State' in its class name. The implementation of PagerAdapter will only keep the current page, and when the page leaves the line of sight, it will be eliminated and its resources will be released; When the page needs to be displayed, a new page will be generated. The biggest advantage of this implementation is that when you have a large number of pages, you don't have to occupy a large amount of memory in memory. When we implement FragmentStatePagerAdapter, we just need to override getCount () and getItem (), and the method meaning is the same as FragmentPagerAdapter. Let's take a look at the implementation case. In fact, it just changed an inheritance class.


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  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>
2

From the code point of view, the inheritance class has changed, and nothing else has changed. Finally, let's implement a simple example;

Let's first write the required Fragment layout. fragment. xml is as follows:


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical" android:layout_width="match_parent"
  android:layout_height="match_parent">

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

FragmentView. java code is as follows:


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  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>
4

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

activity_vp_fg.xml


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  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>
5

VP_FG_Activity.java


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  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>
6

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


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  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>
7

Finally, the data time adapter MyFragmentAdapter is set to ViewPager, thus completing the data filling. It should be noted here that Activity inherits from FragmentActivity, and only FragmentActivity can be embedded with fragment page, but ordinary Activity can't.


Related articles: