使用ViewPager实现三个fragment切换

一、ViewPager的基本用法

1.ViewPager概述

ViewPager是android扩展包v4包中的类,这个类可以让我们左右切换当前的view。我们先来聊聊ViewPager的几个相关知识点:

  • ViewPager类直接继承了ViewGroup类,因此它一个容器类,可以添加其他的view类
  • ViewPager类需要一个PagerAdapter适配器类给它提供数据(这点跟ListView一样需要数据适配器Adater)
  • ViewPager经常和Fragment一起使用,并且官方还提供了专门的FragmentPagerAdapter和FragmentStatePagerAdapter类供Fragment中的ViewPager使用

2.ViewPager使用案例

我们只需在xml布局文件中添加如下代码:
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(作为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>

然后这里我们先创建4个要在ViewPager中显示的界面,代码如下:

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添加view
viewContainter.add(view1);
viewContainter.add(view2);
viewContainter.add(view3);
viewContainter.add(view4);

有了数据后我们就要创建数据适配器了,我们创建一个数据适配器MyPagerAdapter继承自PagerAdapter,在PagerAdapter我们必须重写以下几个方法:

  • int getCount()
    getCount():返回可以滑动的VIew的个数
  • void destroyItem(ViewGroup container, int position,Object object)
    从当前container中删除指定位置的View
  • Object instantiateItem(ViewGroup container, int position)
    将当前视图添加到container中并返回当前View视图
  • boolean isViewFromObject(View arg0, Object arg1)
    该函数用来判断instantiateItem(ViewGroup, int)函数所返回来的Object与一个页面视图是否是代表的同一个视图,官方建议直接返回arg0 == arg1即可。

下面我们给出MyPagerAdapters完整代码:

/**
*   ViewPager的数据适配器
*/
class MyPagerAdapters extends PagerAdapter{
   //返回可以滑动的VIew的个数
   @Override
   public int getCount() {
       return viewContainter.size();
   }
   //滑动切换的时候销毁当前的组件
   @Override
   public void destroyItem(ViewGroup container, int position,
                           Object object) {
       ((ViewPager) container).removeView(viewContainter.get(position));
   }
   //将当前视图添加到container中并返回当前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;
   }

最后我们只要把MyPagerAdapters适配器设置给ViewPager即可:

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

MainActivity完整代码如下:

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开始添加view
        viewContainter.add(view1);
        viewContainter.add(view2);
        viewContainter.add(view3);
        viewContainter.add(view4);
        //设置Adapter
        pager.setAdapter(new MyPagerAdapters());

    }

    /**
    *   ViewPager的数据适配器
    */
    class MyPagerAdapters extends PagerAdapter{
        //返回可以滑动的VIew的个数
        @Override
        public int getCount() {
            return viewContainter.size();
        }
        //滑动切换的时候销毁当前的组件
        @Override
        public void destroyItem(ViewGroup container, int position,
                                Object object) {
            ((ViewPager) container).removeView(viewContainter.get(position));
        }
        //将当前视图添加到container中并返回当前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;
        }
    }
}

运行代码结果如下:

到此,最简单的ViewPager使用方式已经介绍完啦。

3.PagerTitleStrip类和PagerTabStrip类

我们在编写ViewPager的应用时,还会使用到两个组件类分别是PagerTitleStrip类和PagerTabStrip类,PagerTitleStrip类直接继承自ViewGroup类,用于设置每页的标题,而PagerTabStrip类继承PagerTitleStrip类用于控制Tab选择时指示条样式或者标题样式,这两个类也都是容器类。但是有一点我们需要特别需要注意,在定义XML的layout的时候,这两个类必须是ViewPager标签的子标签,不然会出错。由于PagerTabStrip类继承PagerTitleStrip类,因此PagerTabStrip拓展了PagerTitleStrip类功能,所以这里我们仅演示PagerTabStrip用法。
首先我们在activity_main.xml文件中添加PagerTabStrip控件:

<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文件中创建标题数据:

ArrayList<String> titleContainer = new ArrayList<String>();
//页签项

titleContainer.add("今日头条");

titleContainer.add("今天热点");

titleContainer.add("今日财经");

titleContainer.add("今日军事");

想要为每个标签页添加标题,我们必须重写PagerAdapter类中的getPageTitle方法,然后根据位置position从集合数据中获取对应的title返回即可,该方法实现如下:

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

接下来我们来通过PagerTabStrip控件改变每个Tab的下横线指示线的style。代码如下:

 tabStrip = (PagerTabStrip) this.findViewById(R.id.tabstrip);
//取消tab下面的长横线
tabStrip.setDrawFullUnderline(false);
//设置tab的背景色
tabStrip.setBackgroundResource(R.color.bg);
//设置当前tab页签的下划线颜色
tabStrip.setTabIndicatorColorResource(R.color.red);
tabStrip.setTextSpacing(400);

到此标题和指示器都设置完成,下面我们给出改版后的MainActivity代码:

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>();
    ArrayList<String> titleContainer = new ArrayList<String>();

    @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.setBackgroundResource(R.color.bg);
        //设置当前tab页签的下划线颜色
        tabStrip.setTabIndicatorColorResource(R.color.red);
        tabStrip.setTextSpacing(400);

        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 MyPagerAdapters());

    }

    /**
     *   ViewPager的数据适配器
     */
    class MyPagerAdapters extends PagerAdapter{
        //返回可以滑动的VIew的个数
        @Override
        public int getCount() {
            return viewContainter.size();
        }
        //滑动切换的时候销毁当前的组件
        @Override
        public void destroyItem(ViewGroup container, int position,
                                Object object) {
            ((ViewPager) container).removeView(viewContainter.get(position));
        }
        //将当前视图添加到container中并返回当前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;
        }

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

最后我们来运行一下看看效果:

效果算一般吧,实际上在我们开发中很少会使用到PagerTabStrip与PagerTitleStrip,因为他们实现的标题栏效果很不好,不能指定一个页面一次显示一个,或者全部显示,而且标题还跟着界面滑动。因此实际应用中并不建议使用。我们更多的是去自定义指示器,这样的话效果也会更好,好了,到此,本篇到此告一段落。

 

Fragment+ViewPager的基本用法

1.FragmentPagerAdapter与FragmentStatePagerAdapter

当ViewPager与Fragment结合使用时,我们所需要使用的数据适配器就已不再是PagerAdapter而是官方另外提供的FragmentPagerAdapter与FragmentStatePagerAdapter数据适配器,下面我们先来聊聊这两个FragmentPagerAdapter与FragmentStatePagerAdapter的使用方法及其主要区别。

  • FragmentPagerAdapter

FragmentPagerAdapter 继承自 PagerAdapter。相比通用的 PagerAdapter,该类更专注于每一页均为 Fragment 的情况。该类内的每一个生成的 Fragment 都将保存在内存之中,尽管不可见的视图有时会被销毁,但用户所有访问过的fragment都会被保存在内存中,因此fragment实例会保存大量的各种状态,这就造成了很大的内存开销。所以FragmentPagerAdapter比较适用于那些相对静态的页,数量也比较少的应用情景,如主流主界面;如果需要处理有很多页,并且数据动态性较大、占用内存较多的情况,应该使用FragmentStatePagerAdapter。对应实现FragmentPagerAdapter ,我们只需重写getCount()与getItem()两个方法,因此相对于继承自 PagerAdapter,更方便一些。接下来我们来看看如何用代码实现FragmentPagerAdapter

 class MyFragmentAdapter extends FragmentPagerAdapter{

        List<Fragment> list;

        public MyFragmentAdapter(FragmentManager fm,List<Fragment> list) {
            super(fm);
            this.list=list;
        }

        /**
         * 返回需要展示的fragment
         * @param position
         * @return
         */
        @Override
        public Fragment getItem(int position) {
            return list.get(position);
        }

        /**
         * 返回需要展示的fangment数量
         * @return
         */
        @Override
        public int getCount() {
            return list.size();
        }
}

代码相当简单,我们这里简单以下两个函数

  • getItem(int position)

    这个函数实际上是根据下标position需要展示的fragment界面,该方法是在PagerAdapter#instantiateItem()方法中被调用的,大家只要看一下FragmentPagerAdapter源码就清晰了。

  • getCount()
    这个函数就更简单了,返回需要展示的fragment的总个数。

到此我们就对FragmentPagerAdapter介绍完了,下面我们接着看看FragmentStatePagerAdapter类。

  • FragmentStatePagerAdapter

FragmentStatePagerAdapter 和 FragmentPagerAdapter 一样,是继承子 PagerAdapter。但是它们的不同点在于其类名中的 ‘State’ 所表明的含义一样,该 PagerAdapter 的实现将只保留当前页面,当页面离开视线后,就会被消除,释放其资源;而在页面需要显示时,再生成新的页面。这样实现的最大好处在于当拥有大量的页面时,不必在内存中占用大量的内存。我们在实现FragmentStatePagerAdapter是也同样只需重写getCount()与getItem()两个方法,而且其方法含义跟FragmentPagerAdapter是一样的。下面我们来看看实现案例,其实就改了个继承类而已。

class MyFragmentStateAdapter extends FragmentStatePagerAdapter{

        List<Fragment> list;

        public MyFragmentStateAdapter(FragmentManager fm,List<Fragment> list) {
            super(fm);
            this.list=list;
        }

        /**
         * 返回需要展示的fragment
         * @param position
         * @return
         */
        @Override
        public Fragment getItem(int position) {
            return list.get(position);
        }

        /**
         * 返回需要展示的fangment数量
         * @return
         */
        @Override
        public int getCount() {
            return list.size();
        }
    }

从代码的角度来看就换了继承类,其他都没有变化。最后我们来实现一个简单例子;
我们先来编写需要的Fragment布局.fragment.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">

    <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代码如下:

package com.zejian.activity;

package com.zejian.viewpager;

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

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

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

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
       View view= inflater.inflate(R.layout.fragment,null);
        TextView tv= (TextView) view.findViewById(R.id.tv);
        int page=arg.getInt("pager_num");

        if (page==1){
            view.setBackgroundResource(R.color.colorAccent);
        }else if(page==2){
            view.setBackgroundResource(R.color.greed);
        }else if(page==3){
            view.setBackgroundResource(R.color.red);
        }else if(page==4){
            view.setBackgroundResource(R.color.colorPrimary);
        }

        tv.setText(arg.getString("Title"));
        return view;
    }


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

}

Fragment的代码也很清新,我们通过传递过来的参数去判断每个fragment的背景颜色,并设置标题名称,最后返回我们需要展示的view。我们再来看看actvity的布局文件
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.support.v4.view.ViewPager
        android:id="@+id/vp"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

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

VP_FG_Activity.java

package com.zejian.viewpager;

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.ViewPager;

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

/**
 * 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) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_vp_fg);
        viewPager= (ViewPager) findViewById(R.id.vp);
        initData();
    }

    public void initData(){

        List<Fragment> list=new ArrayList<>();

        Bundle bundle1=new Bundle();
        bundle1.putString("Title","第一个Fragment");
        bundle1.putInt("pager_num",1);
        Fragment fg1=FragmentView.newInstance(bundle1);

        Bundle bundle2=new Bundle();
        bundle2.putString("Title","第二个Fragment");
        bundle2.putInt("pager_num",2);
        Fragment fg2=FragmentView.newInstance(bundle2);

        Bundle bundle3=new Bundle();
        bundle3.putString("Title","第三个Fragment");
        bundle3.putInt("pager_num",3);
        Fragment fg3=FragmentView.newInstance(bundle3);

        Bundle bundle4=new Bundle();
        bundle4.putString("Title","第四个Fragment");
        bundle4.putInt("pager_num",4);
        Fragment fg4=FragmentView.newInstance(bundle4);

        list.add(fg1);
        list.add(fg2);
        list.add(fg3);
        list.add(fg4);

        viewPager.setAdapter(new MyFragmentAdapter(getSupportFragmentManager(),list));

    }

    class MyFragmentAdapter extends FragmentPagerAdapter{

        List<Fragment> list;

        public MyFragmentAdapter(FragmentManager fm,List<Fragment> list) {
            super(fm);
            this.list=list;
        }

        /**
         * 返回需要展示的fragment
         * @param position
         * @return
         */
        @Override
        public Fragment getItem(int position) {
            return list.get(position);
        }

        /**
         * 返回需要展示的fangment数量
         * @return
         */
        @Override
        public int getCount() {
            return list.size();
        }
    }
    class MyFragmentStateAdapter extends FragmentStatePagerAdapter{

        List<Fragment> list;

        public MyFragmentStateAdapter(FragmentManager fm,List<Fragment> list) {
            super(fm);
            this.list=list;
        }

        /**
         * 返回需要展示的fragment
         * @param position
         * @return
         */
        @Override
        public Fragment getItem(int position) {
            return list.get(position);
        }

        /**
         * 返回需要展示的fangment数量
         * @return
         */
        @Override
        public int getCount() {
            return list.size();
        }
    }
}

在Activity我们通过以下代码去初始化ViewPager所需要的数据

List<Fragment> list=new ArrayList<>();

Bundle bundle1=new Bundle();
bundle1.putString("Title","第一个Fragment");
bundle1.putInt("pager_num",1);
Fragment fg1=FragmentView.newInstance(bundle1);

Bundle bundle2=new Bundle();
bundle2.putString("Title","第二个Fragment");
bundle2.putInt("pager_num",2);
Fragment fg2=FragmentView.newInstance(bundle2);

Bundle bundle3=new Bundle();
bundle3.putString("Title","第三个Fragment");
bundle3.putInt("pager_num",3);
Fragment fg3=FragmentView.newInstance(bundle3);

Bundle bundle4=new Bundle();
bundle4.putString("Title","第四个Fragment");
bundle4.putInt("pager_num",4);
Fragment fg4=FragmentView.newInstance(bundle4);

list.add(fg1);
list.add(fg2);
list.add(fg3);
list.add(fg4);

viewPager.setAdapter(new MyFragmentAdapter(getSupportFragmentManager(),list));

最后把数据时适配器MyFragmentAdapter设置给ViewPager,这样就完成数据的填充。这里有点要注意的是,Activity继承自FragmentActivity,只有FragmentActivity才能内嵌fragment页面,普通Activity是不行的。我们运行一下程序,效果如下:

到此我们对Fragment+ViewPager的使用方式已经有了比较清晰的了解了,本篇也就告一段落,下篇我们将通过实例来先一个通用的App首页。欢迎继续关注哈。

 

新建一个android项目

先展示效果吧

 

首先看myfragmentPagerAdater这个类的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package com.example.viewpager;
import java.util.List;
import android.support.v4.app.Fragment;   //注意打包是用support.v4的
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
<br>//继承
public class myFragmentPagerAdapter extends FragmentPagerAdapter {
    
    private FragmentManager fragmetnmanager;  //创建FragmentManager
    private List<Fragment> listfragment; //创建一个List<Fragment>
<br>      //定义构造带两个参数
    public myFragmentPagerAdapter(FragmentManager fm,List<Fragment> list) {
        super(fm);
        this.fragmetnmanager=fm;
        this.listfragment=list;
    }
    @Override
    public Fragment getItem(int arg0) {
        // TODO Auto-generated method stub
        return listfragment.get(arg0); //返回第几个fragment
    }
    @Override
    public int getCount() {
        // TODO Auto-generated method stub
        return listfragment.size(); //总共有多少个fragment
    }
    
}

然后到MainActivity初始化ViewPager  (这里还没有图片偏移和链接点击事件的代码 后面讲到)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/*
 * 初始化Viewpager<br>     *
*/
viewpager=(ViewPager) findViewById(R.id.vp); //获取ViewPager
listfragment=new ArrayList<Fragment>(); //new一个List<Fragment>
Fragment f1 = new fragment01();
Fragment f2 = new fragment02();
Fragment f3 = new fragment03();<br>     //添加三个fragment到集合
listfragment.add(f1);
listfragment.add(f2);
listfragment.add(f3);
FragmentManager fm=getSupportFragmentManager();
myFragmentPagerAdapter mfpa=new myFragmentPagerAdapter(fm, listfragment); //new myFragmentPagerAdater记得带上两个参数
viewpager.setAdapter(mfpa);
viewpager.setCurrentItem(0); //设置当前页是第一页

现在到MainActivity中的三个链接的点击代码(这三个是TextView来着)之后就可以点击实现页面调转,但是图片偏移还没实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
/*
 * 初始化链接
 */
t1=(TextView) findViewById(R.id.textView1);
t2=(TextView) findViewById(R.id.textView2);
t3=(TextView) findViewById(R.id.textView3);
t1.setOnClickListener(new OnClickListener() {
    
    @Override
    public void onClick(View v) {
        viewpager.setCurrentItem(0);
        
    }
});
t2.setOnClickListener(new OnClickListener() {
    
    @Override
    public void onClick(View v) {
        
        viewpager.setCurrentItem(1);
    }
});
t3.setOnClickListener(new OnClickListener() {
    
    @Override
    public void onClick(View v) {
        
        viewpager.setCurrentItem(2);
    }
});

然后是图片偏移

1
2
3
private int index; //当前页卡;
private int imgleth; //图片宽度
private int offset; //偏移量
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
  /*
   * 初始化图片
  */
  iv=(ImageView) findViewById(R.id.imageView1);
  //获取图片宽度
  imgleth=BitmapFactory.decodeResource(getResources(), R.drawable.a1).getWidth();
  //获取屏幕宽度
  DisplayMetrics dm=new DisplayMetrics();
  // 把屏幕尺寸信息赋值给DisplayMetrics dm,注意不是set
  getWindowManager().getDefaultDisplay().getMetrics(dm);
  // 屏幕宽度
  int count=dm.widthPixels;
  //计算偏移量
  offset=(count/3-imgleth)/2;
 
  //平移动画(第一页的)
Animation  an=new TranslateAnimation(0, offset, 0, 0);
  an.setFillAfter(true);
  an.setDuration(200);
  iv.setAnimation(an);

最后是偏移图片跟着页面走 只需要在之前的 viewpager.setCurrentItem(0);后面添加即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
viewpager.setOnPageChangeListener(new OnPageChangeListener() {
    
    int one=offset*2+imgleth;//相邻页面的偏移量
    @Override
    public void onPageSelected(int arg0) {
        
        //评议动画
        Animation anima=new TranslateAnimation(index*one+offset,arg0*one+offset,0,0);
        index=arg0; //当前页跟着变
        anima.setFillAfter(true); // 动画终止时停留在最后一帧,不然会回到没有执行前的状态
        anima.setDuration(200);// 动画持续时间0.2秒
        iv.startAnimation(anima);// 是用ImageView来显示动画的
        Toast.makeText(MainActivity.this, "您选择了第"+(index+1)+"个页卡", 100).show(); 
    }
    
    @Override
    public void onPageScrolled(int arg0, float arg1, int arg2) {
        // TODO Auto-generated method stub
        
    }
    
    @Override
    public void onPageScrollStateChanged(int arg0) {
        // TODO Auto-generated method stub
        
    }
});

特别注意打包时候是打v4包(每个fragment也是打v4包)

1
2
3
4
5
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;

TranslateAnimation参数说明:

float fromXDelta:这个参数表示动画开始的点离当前View X坐标上的差值;

float toXDelta, 这个参数表示动画结束的点离当前View X坐标上的差值;

float fromYDelta, 这个参数表示动画开始的点离当前View Y坐标上的差值;

float toYDelta, 这个参数表示动画开始的点离当前View Y坐标上的差值;

这4个参数确定移动的起点和终点