ViewPager深入解析2

转自https://blog.csdn.net/jinxinliu1/article/details/53503109
注意了:ViewPager更多的时候会与Fragment一起使用
没错,在大部分时候,项目中的ViewPager会和Fragment同时出现,每一个ViewPager的页面就是一个Fragment。既然如此,我们当然也要来看看这个知识!继续参考API。

Android提供了一些专门的适配器来让ViewPager与Fragment一起工作,也就是FragmentPagerAdapter与FragmentStatePagerAdapter。

好哒,看来是时候了解下FragmentPagerAdapter和FragmentStatePagerAdapter这一对磨人的小妖精了。我们先来看看FragmentPagerAdapter的API:

1.FragmentPagerAdapter继承自PagerAdapter ,主要用来展示多个Fragment页面,并且每一个Fragment都会被保存在fragment manager中。
2.FragmentPagerAdapter最适用于那种少量且相对静态的页面,例如几个tab页。每一个用户访问过的fragment都会被保存在内存中,尽管他的视图层级可能会在不可见时被销毁。这可能导致大量的内存因为fragment实例能够拥有任意数量的状态。对于较多的页面集合,更推荐使用FragmentStatePagerAdapter。
3.当使用FragmentPagerAdapter的时候对应的ViewPager必须拥有一个有效的ID集。
4.FragmentPagerAdapter的派生类只需要实现getItem(int)和getCount()即可。

再来看看FragmentStatePagerAdapter的API:

1.FragmentStatePagerAdapter继承自PagerAdapter,主要使用Fragment来管理每个页面。这个类同样用来保存和恢复fragment页面的状态。
2.FragmentStatePagerAdapter更多用于大量页面,例如视图列表。当某个页面对用户不再可见时,他们的整个fragment就会被销毁,仅保留fragment状态。相比于FragmentPagerAdapter,这样做的好处是在访问各个页面时能节约大量的内存开销,但代价是在页面切换时会增加非常多的开销。
3.当使用FragmentPagerAdapter(注:API里这里写的是FragmentPagerAdapter,不过貌似应该是FragmentStatePagerAdapter?)的时候对应的ViewPager必须拥有一个有效的ID集。
4.FragmentStatePagerAdapter的派生类只需要实现getItem(int)和getCount()即可。

我们可以看出:FragmentPagerAdapter与FragmentStatePagerAdapter存在着大量相似之处,用法也差不多,他们之间最大的不同在于:用户访问过的页面不可见之后是否会保留在内存中,而这个区别也构成了他们使用场景的不同。

至于这两个适配器的使用其实是很简单的,我们新建一个适配器类MyFragmentAdapter(这篇文章的demo是在上一篇文章的基础上修改的)

MyFragmentAdapter.java

package com.example.viewpagerdemo;

import java.util.List;

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;

public class MyFragmentAdapter extends FragmentPagerAdapter {

    private List<Fragment> fragmentList;
    public MyFragmentAdapter(FragmentManager fm, List<Fragment> fragmentList) {
        super(fm);
        // TODO Auto-generated constructor stub

        this.fragmentList = fragmentList;
    }

    @Override
    public Fragment getItem(int arg0) {
        // TODO Auto-generated method stub
        return fragmentList.get(arg0);
    }

    @Override
    public int getCount() {
        // TODO Auto-generated method stub
        return fragmentList.size();
    }

}

接下来我们创建3个Fragment,布局的话就使用上一篇文章中的3个page。

MyFragment1.java

package com.example.viewpagerdemo;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class MyFragment1 extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        View view = inflater.inflate(R.layout.page1, null);
        return view;
    }
}

MyFragment2和MyFragment3与之类似,就是把布局文件换一下就可以了,当然,实际项目中的fragment是不会这么简单的,我们可以在每个fragment页里面放入各种功能,配合ViewPager就能轻松构成一个APP的首页。
接下来我们只需要在MainActivity中将“数据源”、“视图”、“适配器”关联起来即可,这个和上一篇文章的内容差不多,就是将原来的3个普通页面换成Fragment页面
MainActivity.java

        // ViewPager中包含的页面为普通页面
        /*LayoutInflater inflater = getLayoutInflater();
        page1 = inflater.inflate(R.layout.page1, null);
        page2 = inflater.inflate(R.layout.page2, null);
        page3 = inflater.inflate(R.layout.page3, null);
        pageList = new ArrayList<View>();
        pageList.add(page1);
        pageList.add(page2);
        pageList.add(page3);
        myPagerAdapter = new MyPagerAdapter(pageList);
        myViewPager.setAdapter(myPagerAdapter);*/

        // ViewPager中包含的页面为Fragment,用法与前面的普通适配器一模一样
        MyFragment1 myFragment1 = new MyFragment1();
        MyFragment2 myFragment2 = new MyFragment2();
        MyFragment3 myFragment3 = new MyFragment3();

        List<Fragment> fragmentList = new ArrayList<Fragment>();
        fragmentList.add(myFragment1);
        fragmentList.add(myFragment2);
        fragmentList.add(myFragment3);

        MyFragmentAdapter myFragmentAdapter = new MyFragmentAdapter(getSupportFragmentManager(), fragmentList);
        myViewPager.setAdapter(myFragmentAdapter);

代码很简单吧,哦,有一点别忘记,如果要使用FragmentPagerAdapter的话,我们的MainActivity必须继承FragmentActivity而不是Activity。OK,大家可以运行一下项目,效果应该是跟上一篇文章里一样的,不过因为这里的每个页面都是Fragment,所以相比于普通的View,你可以在每个页面自定义非常多的功能。

不过
小伙伴们有没有觉得,相比于很多实际项目,我们的demo还是少了什么?没错,一般的APP在使用viewpager的时候,都会有一个tab页(只不过有一些在页面顶部,有一些在页面底部)。PagerTabStrip与PagerTitleStrip这两个类就是专门用来实现ViewPager的标题的,不过实际使用中基本上没他们什么事情(摸摸这两个孩子),所以我们这里也就不讲解了。一般会自己重新写一个Tab页,我们赶紧来实现一下吧。
我们先来准备一个tab页的布局,很简单,就是3个TextView。
tab.xml

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

    <TextView
        android:id="@+id/tv_tab0"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:text="小火龙"
        android:textSize="16sp"
        android:gravity="center"
        />

    <TextView 
        android:id="@+id/tv_tab1"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:text="杰尼龟"
        android:textSize="16sp"
        android:gravity="center"
        />

    <TextView
        android:id="@+id/tv_tab2"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:text="妙蛙种子"
        android:textSize="16sp"
        android:gravity="center"
        />

</LinearLayout>

既然有了tab页,我们就要考虑Tab页与ViewpPger的交互了,一般情况下我们需要实现下面2中功能:
1、点击一个选项卡的时候,ViewPager滑动到对应的页面。
2、滑动ViewPager页面时,Tab滑动到对应的选项卡。
我们先来看第一个功能,这个功能其实很简单,涉及到的知识点就是setCurrentItem(int position),我们直接来看代码吧

    @Override
    public void onClick(View v) {
        // TODO Auto-generated method stub
        switch (v.getId()) {
        case R.id.tv_tab0:
            myViewPager.setCurrentItem(0);
            break;
        case R.id.tv_tab1:
            myViewPager.setCurrentItem(1);
            break;
        case R.id.tv_tab2:
            myViewPager.setCurrentItem(2);
            break;
        default:
            break;
        }

接着是第二个功能,这个功能涉及到的知识点就复杂一些了,这里我们需要实现一个接口OnPageChangeListener。我们来看看OnPageChangeListener的API
我们总共需要实现3个方法,这3个方法基本上看名字就知道是什么作用,皮卡丘就不翻译啦,直接来讲解一下他们的用法:

onPageScrollStateChanged(int state):当页面的滑动状态改变时该方法会被触发,页面的滑动状态有3个:“0”表示什么都不做,“1”表示开始滑动,“2”表示结束滑动。

onPageScrolled(int position, float positionOffset, int positionOffsetPixels):页面在滑动过程中不停触发该方法:“position”按照api的解释是“目前显示在屏幕上的第一个页面,只要positionOffset不为0,那么他后面的页面同样是可见的”(这一点非常重要!!!皮卡丘因为当初并没有看API,而是想当然得觉得position是当前页面,所以绕了不少弯路,在做了大量的debug和log之后才发现错误在哪……所以小伙伴们一定要好好掌握基础知识啊!),“positionOffset”指的是偏移量的百分比,“positionOffsetPixels”指的是偏移量的数值。

onPageSelected(int position):ViewPager跳转到新页面时触发该方法,position表示新页面的位置。

我们继续看我们之前提的需求2,小伙伴们是不是已经觉得很简单啦?没错,只需要在onPageSelected(int position)中设置对应的方法即可。

MainActivity.java

    ......

    @Override
    public void onPageSelected(int position) {
        // TODO Auto-generated method stub
        switch (position) {
        case 0:
            tv_tab0.setTextColor(Color.RED);
            tv_tab1.setTextColor(Color.BLACK);
            tv_tab2.setTextColor(Color.BLACK);
            break;
        case 1:
            tv_tab0.setTextColor(Color.BLACK);
            tv_tab1.setTextColor(Color.BLUE);
            tv_tab2.setTextColor(Color.BLACK);
            break;
        case 2:
            tv_tab0.setTextColor(Color.BLACK);
            tv_tab1.setTextColor(Color.BLACK);
            tv_tab2.setTextColor(Color.GREEN);
            break;
        default:
            break;
        }

    ......

不过总觉得,名字和图片之间是不是应该有条下划线来区分下比较好呢?那么这条下划线应该具有怎么样的功能呢?很多APP的实现方式是,当ViewPager的图片页面切换完成之后,下划线就从原来的位置滑动到新的位置。这个实现是比较简单的……前提是你对属性动画比较了解的话……
我们先把下划线在布局中画出来,因为在布局文件里面我们没办法确定实际屏幕的宽度,所以我们可以先给下划线随意设置一个宽度,然后在Java代码中将其设置为整个屏幕宽度的三分之一。
activity_main.xml

...

<ImageView
        android:id="@+id/line_tab"
        android:layout_width="100dp"
        android:layout_height="1dp"
        android:background="#6E0000FF"
        />

...

MainActivity.java

    ......

    /**
     * 重新设定line的宽度
     */
    private void initLineImage() {
        // TODO Auto-generated method stub

        /**
         * 获取屏幕的宽度
         */
        DisplayMetrics dm = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(dm);
        int screenW = dm.widthPixels;

        /**
         * 重新设置下划线的宽度
         */
        LayoutParams lp = line_tab.getLayoutParams();
        lp.width = screenW / 3;
        line_tab.setLayoutParams(lp);

        moveOne = lp.width; // 滑动一个页面的距离
    }

    ......

然后我们来写一个动画方法

MainActivity.java

    ......

    private void movePositionX(int toPosition) {
        // TODO Auto-generated method stub
        float curTranslationX = line_tab.getTranslationX();
        float toPositionX = moveOne * toPosition;
        ObjectAnimator animator = ObjectAnimator.ofFloat(line_tab, "translationX", curTranslationX, toPositionX);
                animator.setDuration(500);
        animator.start();
    }

    ......

这个方法的功能就是让下划线滑动到新的页面。我们把他加入到onPageSelected方法中:

MainActivity.java

    ......
    @Override
    public void onPageSelected(int position) {
        // TODO Auto-generated method stub
        switch (position) {
        case 0:
            tv_tab0.setTextColor(Color.RED);
            tv_tab1.setTextColor(Color.BLACK);
            tv_tab2.setTextColor(Color.BLACK);
            movePositionX(0);
            break;
        case 1:
            tv_tab0.setTextColor(Color.BLACK);
            tv_tab1.setTextColor(Color.BLUE);
            tv_tab2.setTextColor(Color.BLACK);
            movePositionX(1);
            break;
        case 2:
            tv_tab0.setTextColor(Color.BLACK);
            tv_tab1.setTextColor(Color.BLACK);
            tv_tab2.setTextColor(Color.GREEN);
            movePositionX(2);
            break;
        default:
            break;
        }
    }

    ......

这样的效果基本上已经可以满足大部分的需求了。但是!其实我们可以考虑下,能不能让这个效果更加好玩:当我们滑动页面,但是页面并未真正切换的时候,下划线能否也跟着滑动呢?如果能实现这样的效果,那么用户体验一定非常的不错呢!
这个功能应该考虑:
1、手指滑动的时候,下划线要跟着滑动的偏移量而进行相应的移动
2、手指停止滑动的时候,下划线要逐渐移动到目标位置(如果滑动偏移量不大的话就会回到原来位置)
所以我们需要判断手指什么时候开始滑动,什么时候停止滑动,大家还记得API中的描述吗?没错,就是onPageScrollStateChanged。

MainActivity.java

    ......

    @Override
    public void onPageScrollStateChanged(int state) {
        // TODO Auto-generated method stub
        switch (state) {
        case 1:
            isScrolling = true;
            isBackScrolling = false;
            break;
        case 2:
            isScrolling = false;
            isBackScrolling = true;
            break;
        default:
            isScrolling = false;
            isBackScrolling = false;
            break;
        }

    }

    ......

isScrolling代表的是手指正在滑动,isBackScrolling代表的是手指离开,页面继续滚动或者回滚。这个逻辑并不复杂,小伙伴们自己好好理解下吧。
接下来,是在onPageScrolled中加入滑动的动画,我们在原来的滑动动画上进行一定的修改

MainActivity.java

    ......

    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
        // TODO Auto-generated method stub
        if (isScrolling) {
            movePositionX(position, moveOne * positionOffset);
        }

        if (isBackScrolling) {
            movePositionX(position);
        }

    }

    ......

    /**
     * 下划线跟随手指的滑动而移动
     * @param toPosition
     * @param positionOffsetPixels
     */
    private void movePositionX(int toPosition, float positionOffsetPixels) {
        // TODO Auto-generated method stub
        float curTranslationX = line_tab.getTranslationX();
        float toPositionX = moveOne * toPosition + positionOffsetPixels;
        ObjectAnimator animator = ObjectAnimator.ofFloat(line_tab, "translationX", curTranslationX, toPositionX);
        animator.setDuration(500);
        animator.start();
    }

    /**
     * 下划线滑动到新的选项卡中
     * @param toPosition
     */
    private void movePositionX(int toPosition) {
        // TODO Auto-generated method stub
        movePositionX(toPosition, 0);
    }

    ......

这里的逻辑其实还是有点小复杂的,但主要麻烦在计算动画的目标坐标的数学逻辑,代码上的逻辑倒是蛮简单的啦,功能顺利实现!
然而!在模拟器上运行成功的demo,放到真机上却出了问题:下划线居然不跟随手指的滑动而移动!
出问题了自然要去打印日志来检查问题,在打印log的过程中,我们可以发现,在真机上onPageScrolled方法的触发频率比模拟器上高了不知道多少倍,这让我想到一开始设计的时候考虑过的问题:是否需要设定一个时间间隔,每隔了这个时间间隔才让动画执行一次(当时考虑这个问题的时候更多的是从执行效率的角度来考虑,不过当时在模拟器上打印日志的时候发现onPageScrolled触发的频率本来就不高,所以就没加这个限制)。OK,那让我们在onPageScrolled中增加一个时间间隔:
MainActivity.java

    ......

    currentTime = System.currentTimeMillis();
    if (isScrolling && (currentTime - startTime > 200)) {
        Log.i("MainActivity", "position = " + position);
        movePositionX(position, moveOne * positionOffset);
        startTime = currentTime;
    }

    ......

好啦,执行代码,在真机上运行~功能果然能正常运行啦,可喜可贺可喜可贺啊。
本次demo所有代码:
activity_main.xml

<LinearLayout 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:orientation="vertical"
     >

    <include layout="@layout/tab" />

    <ImageView
        android:id="@+id/line_tab"
        android:layout_width="100dp"
        android:layout_height="1dp"
        android:background="#6E0000FF"
        />

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

</LinearLayout>

page1.xml

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

    <ImageView 
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:src="@drawable/view1" />

</RelativeLayout>

page2.xml

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

    <ImageView 
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:src="@drawable/view2" />

</RelativeLayout>

page3.xml

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

    <ImageView 
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:src="@drawable/view3" />

</RelativeLayout>

tab.xml

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

    <TextView
        android:id="@+id/tv_tab0"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:text="小火龙"
        android:textSize="16sp"
        android:gravity="center"
        />

    <TextView 
        android:id="@+id/tv_tab1"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:text="杰尼龟"
        android:textSize="16sp"
        android:gravity="center"
        />

    <TextView
        android:id="@+id/tv_tab2"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:text="妙蛙种子"
        android:textSize="16sp"
        android:gravity="center"
        />

</LinearLayout>

MainActivity.java

package com.example.viewpagerdemo;

import java.util.ArrayList;
import java.util.List;

import android.os.Bundle;
import android.animation.ObjectAnimator;
import android.graphics.Color;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.ImageView;
import android.widget.TextView;

public class MainActivity extends FragmentActivity implements OnPageChangeListener, OnClickListener {

    private ViewPager myViewPager; // 要使用的ViewPager

    private View page1, page2, page3; // ViewPager包含的页面

    private List<View> pageList; // ViewPager包含的页面列表,一般给adapter传的是一个list

    private MyPagerAdapter myPagerAdapter; // 适配器

    private TextView tv_tab0, tv_tab1, tv_tab2; // 3个选项卡

    private ImageView line_tab; // tab选项卡的下划线

    private int moveOne = 0; // 下划线移动一个选项卡

    private boolean isScrolling = false; // 手指是否在滑动

    private boolean isBackScrolling  = false; // 手指离开后的回弹

    private long startTime = 0;

    private long currentTime = 0;

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

        initView();
        initLineImage();
    }

    /**
     * 重新设定line的宽度
     */
    private void initLineImage() {
        // TODO Auto-generated method stub

        /**
         * 获取屏幕的宽度
         */
        DisplayMetrics dm = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(dm);
        int screenW = dm.widthPixels;

        /**
         * 重新设置下划线的宽度
         */
        LayoutParams lp = line_tab.getLayoutParams();
        lp.width = screenW / 3;
        line_tab.setLayoutParams(lp);

        moveOne = lp.width; // 滑动一个页面的距离
    }

    private void initView() {
        // TODO Auto-generated method stub
        myViewPager = (ViewPager) findViewById(R.id.myViewPager);

        // ViewPager中包含的页面为普通页面
        /*LayoutInflater inflater = getLayoutInflater();
        page1 = inflater.inflate(R.layout.page1, null);
        page2 = inflater.inflate(R.layout.page2, null);
        page3 = inflater.inflate(R.layout.page3, null);
        pageList = new ArrayList<View>();
        pageList.add(page1);
        pageList.add(page2);
        pageList.add(page3);
        myPagerAdapter = new MyPagerAdapter(pageList);
        myViewPager.setAdapter(myPagerAdapter);*/

        // ViewPager中包含的页面为Fragment,用法与前面的普通适配器一模一样
        MyFragment1 myFragment1 = new MyFragment1();
        MyFragment2 myFragment2 = new MyFragment2();
        MyFragment3 myFragment3 = new MyFragment3();

        List<Fragment> fragmentList = new ArrayList<Fragment>();
        fragmentList.add(myFragment1);
        fragmentList.add(myFragment2);
        fragmentList.add(myFragment3);

        MyFragmentAdapter myFragmentAdapter = new MyFragmentAdapter(getSupportFragmentManager(), fragmentList);
        myViewPager.setAdapter(myFragmentAdapter);

        tv_tab0 = (TextView) findViewById(R.id.tv_tab0);
        tv_tab1 = (TextView) findViewById(R.id.tv_tab1);
        tv_tab2 = (TextView) findViewById(R.id.tv_tab2);
        myViewPager.setCurrentItem(0);
        tv_tab0.setTextColor(Color.RED);
        tv_tab1.setTextColor(Color.BLACK);
        tv_tab2.setTextColor(Color.BLACK);

        tv_tab0.setOnClickListener(this);
        tv_tab1.setOnClickListener(this);
        tv_tab2.setOnClickListener(this);

        myViewPager.setOnPageChangeListener(this);

        line_tab = (ImageView) findViewById(R.id.line_tab);
    }

    @Override
    public void onPageScrollStateChanged(int state) {
        // TODO Auto-generated method stub
        switch (state) {
        case 1:
            isScrolling = true;
            isBackScrolling = false;
            break;
        case 2:
            isScrolling = false;
            isBackScrolling = true;
            break;
        default:
            isScrolling = false;
            isBackScrolling = false;
            break;
        }

    }

    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
        // TODO Auto-generated method stub
        currentTime = System.currentTimeMillis();
        if (isScrolling && (currentTime - startTime > 200)) {
            movePositionX(position, moveOne * positionOffset);
            startTime = currentTime;
        }

        if (isBackScrolling) {
            movePositionX(position);
        }

    }

    @Override
    public void onPageSelected(int position) {
        // TODO Auto-generated method stub
        switch (position) {
        case 0:
            tv_tab0.setTextColor(Color.RED);
            tv_tab1.setTextColor(Color.BLACK);
            tv_tab2.setTextColor(Color.BLACK);
            movePositionX(0);
            break;
        case 1:
            tv_tab0.setTextColor(Color.BLACK);
            tv_tab1.setTextColor(Color.BLUE);
            tv_tab2.setTextColor(Color.BLACK);
            movePositionX(1);
            break;
        case 2:
            tv_tab0.setTextColor(Color.BLACK);
            tv_tab1.setTextColor(Color.BLACK);
            tv_tab2.setTextColor(Color.GREEN);
            movePositionX(2);
            break;
        default:
            break;
        }
    }

    /**
     * 下划线跟随手指的滑动而移动
     * @param toPosition
     * @param positionOffsetPixels
     */
    private void movePositionX(int toPosition, float positionOffsetPixels) {
        // TODO Auto-generated method stub
        float curTranslationX = line_tab.getTranslationX();
        float toPositionX = moveOne * toPosition + positionOffsetPixels;
        ObjectAnimator animator = ObjectAnimator.ofFloat(line_tab, "translationX", curTranslationX, toPositionX);
        animator.setDuration(500);
        animator.start();
    }

    /**
     * 下划线滑动到新的选项卡中
     * @param toPosition
     */
    private void movePositionX(int toPosition) {
        // TODO Auto-generated method stub
        movePositionX(toPosition, 0);
    }

    @Override
    public void onClick(View v) {
        // TODO Auto-generated method stub
        switch (v.getId()) {
        case R.id.tv_tab0:
            myViewPager.setCurrentItem(0);
            break;
        case R.id.tv_tab1:
            myViewPager.setCurrentItem(1);
            break;
        case R.id.tv_tab2:
            myViewPager.setCurrentItem(2);
            break;
        default:
            break;
        }
    }

}

MyFragment1.java

package com.example.viewpagerdemo;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class MyFragment1 extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        View view = inflater.inflate(R.layout.page1, null);
        return view;
    }
}

MyFragment2.java

package com.example.viewpagerdemo;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class MyFragment2 extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        View view = inflater.inflate(R.layout.page2, null);
        return view;
    }
}

MyFragment3.java

package com.example.viewpagerdemo;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class MyFragment3 extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        View view = inflater.inflate(R.layout.page3, null);
        return view;
    }
}

MyFragmentAdapter.java

package com.example.viewpagerdemo;

import java.util.List;

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;

public class MyFragmentAdapter extends FragmentPagerAdapter {

    private List<Fragment> fragmentList;
    public MyFragmentAdapter(FragmentManager fm, List<Fragment> fragmentList) {
        super(fm);
        // TODO Auto-generated constructor stub

        this.fragmentList = fragmentList;
    }

    @Override
    public Fragment getItem(int arg0) {
        // TODO Auto-generated method stub
        return fragmentList.get(arg0);
    }

    @Override
    public int getCount() {
        // TODO Auto-generated method stub
        return fragmentList.size();
    }

}

MyPagerAdapter.java

package com.example.viewpagerdemo;

import java.util.List;

import android.support.v4.view.PagerAdapter;
import android.view.View;
import android.view.ViewGroup;

public class MyPagerAdapter extends PagerAdapter {

    private List<View> pageList;

    public MyPagerAdapter(List<View> pageList) {
        this.pageList = pageList;
    }

    @Override
    public int getCount() {
        // TODO Auto-generated method stub

        // 返回要展示的图片数量
        return pageList.size();
    }

    @Override
    public boolean isViewFromObject(View arg0, Object arg1) {
        // TODO Auto-generated method stub

        // 刚开始用viewpager就直接写“return arg0 == arg1;”就好啦
        return arg0 == arg1;
    }

    @Override
    public Object instantiateItem(ViewGroup container, int position) {
        // TODO Auto-generated method stub

        // 获取指定位置的控件,页面的事件都可以在这里写
        View view = pageList.get(position);

        // 将指定位置的View加入到ViewGroup
        container.addView(view);

        // 将View作为key返回
        return view;
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        // TODO Auto-generated method stub

        // 将当前位置的View移除
        container.removeView(pageList.get(position));
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值