ViewPager,ViewPager实现的功能,setOnPageChangeListener的三个方法,pager error

ViewPager

ViewPager的简介

ViewPager是android扩展包v4包中的类,这个类可以让用户左右切换当前的view。

所以这时候定义View要这么定义android.support.v4.view.ViewPager

我们首先来看看API对于这个类的表述:

Layout manager that allows the user to flip left and right through pages of data. You supply an implementation of a PagerAdapter to generate the pages that the view shows.
Note this class is currently under early design and development. The API will likely change in later updates of the compatibility library, requiring changes to the source code of apps when they are compiled against the newer version.
ViewPager is most often used in conjunction with Fragment, which is a convenient way to supply and manage the lifecycle of each page. There are standard adapters implemented for using fragments with the ViewPager, which cover the most common use cases. These are FragmentPagerAdapter andFragmentStatePagerAdapter; each of these classes have simple code showing how to build a full user interface with them.

在编写ViewPager的应用的使用,还需要使用两个组件类分别是PagerTitleStrip类和PagerTabStrip类,PagerTitleStrip类直接继承自ViewGroup类,而PagerTabStrip类继承PagerTitleStrip类,所以这两个类也是容器类。但是有一点需要注意,在定义XML的layout的时候,这两个类必须是ViewPager标签的子标签,不然会出错。

ViewPager实现的功能

ViewPager类提供了多界面切换的新效果,
新效果有如下特征:

  • <1>当前显示一组界面中的其中一个界面;
  • <2>当用户通过左右滑动界面时,当前的屏幕显示当前界面和下一个界面的一部分;
  • <3>滑动结束后,界面自动跳转到当前选择的界面中。

setOnPageChangeListener的三个方法

  • 1.onPageSelected(int position):这个方法有一个参数position,代表哪个页面被选中。当用手指滑动翻页的时候,如果翻动成功了(滑动的距离够长),手指抬起来就会立即执行这个方法,position就是当前滑动到的页面。如果直接setCurrentItem翻页,那position就和setCurrentItem的参数一致,这种情况在onPageScrolled执行方法前就会立即执行。

  • 2.onPageScrolled(int position,float positionOffset, int positionOffsetPixels):这个方法会在屏幕滚动过程中不断被调用。
    有三个参数,第一个position,这个参数要特别注意一下。当用手指滑动时,如果手指按在页面上不动,position和当前页面index是一致的;如果手指向左拖动(相应页面向右翻动),这时候position大部分时间和当前页面是一致的,只有翻页成功的情况下最后一次调用才会变为目标页面;如果手指向右拖动(相应页面向左翻动),这时候position大部分时间和目标页面是一致的,只有翻页不成功的情况下最后一次调用才会变为原页面。
    当直接设置setCurrentItem翻页时,如果是相邻的情况(比如现在是第二个页面,跳到第一或者第三个页面),如果页面向右翻动,大部分时间是和当前页面是一致的,只有最后才变成目标页面;如果向左翻动,position和目标页面是一致的。这和用手指拖动页面翻动是基本一致的。
    如果不是相邻的情况,比如我从第一个页面跳到第三个页面,position先是0,然后逐步变成1,然后逐步变成2;我从第三个页面跳到第一个页面,position先是1,然后逐步变成0,并没有出现为2的情况。
    positionOffset是当前页面滑动比例,如果页面向右翻动,这个值不断变大,最后在趋近1的情况后突变为0。如果页面向左翻动,这个值不断变小,最后变为0。
    positionOffsetPixels是当前页面滑动像素,变化情况和positionOffset一致。

  • 3.onPageScrollStateChanged(int state):这个方法在手指操作屏幕的时候发生变化。有三个值:0(END),1(PRESS) , 2(UP) 。
    当用手指滑动翻页时,手指按下去的时候会触发这个方法,state值为1,手指抬起时,如果发生了滑动(即使很小),这个值会变为2,然后最后变为0 。总共执行这个方法三次。一种特殊情况是手指按下去以后一点滑动也没有发生,这个时候只会调用这个方法两次,state值分别是1,0 。
    当setCurrentItem翻页时,会执行这个方法两次,state值分别为2 , 0 。

三个方法的执行顺序为:用手指拖动翻页时,最先执行一遍onPageScrollStateChanged(1),然后不断执行onPageScrolled,放手指的时候,直接立即执行一次onPageScrollStateChanged(2),然后立即执行一次onPageSelected,然后再不断执行onPageScrollStateChanged,最后执行一次onPageScrollStateChanged(0)。
其它的情况由这个可以推出来,不再赘述。

pager.setCurrentItem(0)的使用

pager.setCurrentItem(0)直接设置显示的页面。0代表第一个页面,1代表第二个。

简单小实例

layout.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.PagerTabStrip
        android:id="@+id/tabstrip"
        android:layout_width="wrap_content"
        android:layout_height="50dip"
        android:gravity="center" />
</android.support.v4.view.ViewPager>

</RelativeLayout>

MainActivity.java

  • 1.先找到viewPager和pagerTabStrip。

  • 2.定义两个Array来当容器一个装载view一个装载title

  • 3.pagerTabStrip对设置

  • 4.把view和title装载进去
  • 5.设置Adapter

    package com.example.android_viewpager1;

    import java.util.ArrayList;

    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.support.v4.view.ViewPager.OnPageChangeListener;
    import android.util.Log;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;

    public class MainActivity extends Activity {

    ViewPager pager = null;
    PagerTabStrip tabStrip = null;
    ArrayList viewContainter = new ArrayList();
    ArrayList titleContainer = new ArrayList();
    public String TAG = “tag”;

    @SuppressLint(“ResourceAsColor”)
    @Override
    protected void onCreate(Bundle savedInstanceState) {

      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
    
      pager = (ViewPager) this.findViewById(R.id.viewpager);
      tabStrip = (PagerTabStrip) this.findViewById(R.id.tabstrip);
      //取消tab下面的长横线
      tabStrip.setDrawFullUnderline(false);
      //设置tab的背景色
      tabStrip.setBackgroundColor(this.getResources().getColor(R.color.bg));
      //设置当前tab页签的下划线颜色
      tabStrip.setTabIndicatorColor(this.getResources().getColor(R.color.red));
      tabStrip.setTextSpacing(200);
    
      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开始添加view
      viewContainter.add(view1);
      viewContainter.add(view2);
      viewContainter.add(view3);
      viewContainter.add(view4);
    //页签项
      titleContainer.add("网易新闻");
      titleContainer.add("网易体育");
      titleContainer.add("网易财经");
      titleContainer.add("网易女人");
    
      pager.setAdapter(new PagerAdapter() {
    
          //viewpager中的组件数量
          @Override
          public int getCount() {
              return viewContainter.size();
          }
        //滑动切换的时候销毁当前的组件
          @Override
          public void destroyItem(ViewGroup container, int position,
                  Object object) {
              ((ViewPager) container).removeView(viewContainter.get(position));
          }
        //每次滑动的时候生成的组件
          @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;
          }
    
          @Override
          public int getItemPosition(Object object) {
              return super.getItemPosition(object);
          }
    
          @Override
          public CharSequence getPageTitle(int position) {
              return titleContainer.get(position);
          }
      });
    
      pager.setOnPageChangeListener(new OnPageChangeListener() {
          @Override
          public void onPageScrollStateChanged(int arg0) {
              Log.d(TAG, "--------changed:" + arg0);
          }
    
          @Override
          public void onPageScrolled(int arg0, float arg1, int arg2) {
              Log.d(TAG, "-------scrolled arg0:" + arg0);
              Log.d(TAG, "-------scrolled arg1:" + arg1);
              Log.d(TAG, "-------scrolled arg2:" + arg2);
          }
    
          @Override
          public void onPageSelected(int arg0) {
              Log.d(TAG, "------selected:" + arg0);
          }
      });
    

    }

    }

程式中要使用ViewPager來顯示資訊必須自己繼承PagerAdapter,來完成手指滑動切換視窗的動作。

ViewPage :Required method instantiateItem was not overridde

错误代码提示

java.lang.UnsupportedOperationException: Required method instantiateItem was not overridden

解决办法
把return super.instantiateItem(container, position);

换成:

return container;

pager错误之二

java.lang.UnsupportedOperationException: Required method destroyItem was not overridden

这里说必须的方法没有实现,因为先super了。所以就没有实现了。把super删除就可以实现

//每次滑动删除的页面
    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {

//就是删除这行        super.destroyItem(container, position, object);
        ((ViewPager) container).removeView(viewContainter.get(position));
    }

pager错误之三

页面没有显示出来,

解决过程

  • 1.查看页面本身是否有问题
  • 2.ArrayList有没有添加页面
  • 3.在instantiateItem中有没有添加页面并返回页面。

我的原因是没有返回页面所以导致错误

//每次滑动增加的页面

        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            container.addView(viewContainter.get(position));

            return viewContainter.get(position);
        }

pager错误之四

pager.setCurrentItem(1);

设置初始值没有反应。
设置的时候要放在Adapter里面


设置只可以通过点选,而不是滑动来切换页面

  • 1.首先去掉layout中PagerTabStrip,采用TextView来当tab
  • 2.点击TextView的时候再通过pager.setCurrentItem(0)来设置切换的页面