Android攻城狮 ViewPager(实现导航)

使用ViewPager实现导航
ViewPager可以使视图左右滑动
ViewPager的声明:<android.support.v4.view.ViewPager> 这么写的原因是为了解决版本兼容性问题。其中android.support.v4是谷歌为了解决版本系统碎片化的问题所提供的兼容的包,主要解决向下兼容的问题,能让高版本的控件在低版本的控件中使用
---------------------------
将Layout布局转换为View对象
(1) LayoutInflater lf = getLayoutInflater().from(this);
(2) View.inflater( context, resource, root )
那么,ViewPager到底是什么东西呢?我们可以把ViewPager视作一个容器,里面可以放置两种东西,一种是View对象,一种是Fragment。
例如,微信顶部导航包括“聊天”、“发现”、“通讯录”,这就相当于放置了3个View,每个View对应着布局文件。ViewPager的数据源便相当于View对象或Fragment对象的集合。
----------------------------
Adapter的配置
1. PagerAdaper 数据源:List<View>
2. FragmentPagerAdapter 数据源:List<Fragment>
3. FragmentStatePagerAdapter 数据源:List<Fragment>

准备数据源 --> 准备适配器 -->加载适配器



适配器分为两类,分别对应View的集合和Fragment集合




view 对象对应的适配器是 PagerAdapter,需要新建一个类去继承PagerAdapter。这一点和之前学的适配器不一样。我们要在MainActivity中用这个类去创建适配器对象。
--------------------------------------------------------------------
该类需要继承 4 个方法(默认是2个,需要再扩展2个)为的是让ViewPager可以自己去管理自己的数据源,这里也就是View对象。
1. getCount(): 返回页卡的数量;
2. isViewFromObject(View view, Object object): 判断view是否来自对象
3. instantiateItem(ViewGroup container, int position):实例化一个页卡
4. destroyItem(ViewGroup container, int position, Object object):销毁一个页卡
然后需要构建有参的构造方法:
private List<View>viewList;
    //有参构造方法
    public MyPagerAdapter(List<View>viewList){
        this.viewList=viewList;
    }
-------------------------------------------------------
ViewPager做管理的时候,一般是三个三个地加载,例如当前显示的是view2,它前面是 view1、下一个是 view3,这三个页卡同时加载在一个界面中,而view4还没有加载。继续向右滑动,view4被实例化,显示的是view3,前面是view2,后面是view4,而 view1 则被移除掉了。

ViewPager设置标题
1. 在 main.xml文件中的ViewPager中添加控件<android.support.v4.view.PagerTabStrip>;
2. 在 MainActivity中创建 PagerTabStrip 对象tab;
3. 注意标题也需要存放在List集合里,所以要声明集合 List<String> titleList;
4. 为ViewPager页卡设置标题
    实例化标题集合: titleList = new ArrayList<String>();
    添加标题:titleList.add("第一页"); titleList.add("第一页"); 等等。。。
5. 为了将标题集合传给ViewPager,需要改写适配器的构造方法,向构造方法添加参数List<String>;
private List<String> titleList;    
    //有参构造方法
    public MyPagerAdapter(List<View>viewList,List<String> titleList){
        this.viewList=viewList;
        this.titleList=titleList;
    }
6. 在适配器类中重写方法 getPageTitle():
@Override
    public CharSequence getPageTitle(int position) {
        return titleList.get(position);
    }
7. 在 MianActivity 加载适配器
MyPagerAdapter adapter = new MyPagerAdapter(viewList,titleList);
8.可以为为ViewPager设置属性,显得更美观(在此之前要初始化tab):tab.setBackgroundColor(Color.RED)
-------------------------------
如果在 main.xml同时写上 <android.support.v4.view.PagerTabStrip> 和 <android.support.v4.view.PagerTitleStrip>,则前者会失效

//--------------------------mainActivity-------------------------------------
  1 package com.example.zy_viewpager;
  2 
  3 import java.util.ArrayList;
  4 import java.util.List;
  5 
  6 import android.support.v4.app.Fragment;
  7 import android.support.v4.app.FragmentActivity;
  8 import android.support.v4.view.PagerTabStrip;
  9 import android.support.v4.view.ViewPager;
 10 import android.support.v4.view.ViewPager.OnPageChangeListener;
 11 import android.app.Activity;
 12 import android.graphics.Color;
 13 import android.os.Bundle;
 14 import android.view.LayoutInflater;
 15 import android.view.Menu;
 16 import android.view.MenuItem;
 17 import android.view.View;
 18 import android.view.ViewGroup;
 19 import android.widget.Toast;
 20 import android.os.Build;
 21 //ViewPager实现导航
 22 
 23 
 24 
 25 //PagerAdapter 数据源 List<View>-------xml(view1-4)
 26 //FragmentPagerAdapter 数据源 List<Fragment>----xml(fragment1-4分别加载view1-4)---继承FragmentActivity
 27 //FragmentStatePagerAdapter 数据源 List<Fragment>
 28 public class MainActivity extends FragmentActivity implements OnPageChangeListener {
 29     private List<View> viewList;//------xml-view-
 30     private ViewPager Pager;
 31     
 32     private PagerTabStrip tap;
 33     private List<String> titileList;//标题数据
 34     // 如果在 main.xml同时写上 <android.support.v4.view.PagerTabStrip> 和
 35     // <android.support.v4.view.PagerTitleStrip>,则前者会失效
 36 
 37     private List<Fragment> fragmentlist;
 38 
 39     @Override
 40     protected void onCreate(Bundle savedInstanceState) {
 41         super.onCreate(savedInstanceState);
 42         setContentView(R.layout.main);
 43         Pager = (ViewPager) findViewById(R.id.pager);
 44         viewList = new ArrayList<View>();
 45         // 第一种:通过view对象去作viewpager的数据源
 46         View view1 = View.inflate(this, R.layout.view1, null);
 47         View view2 = View.inflate(this, R.layout.view2, null);
 48         View view3 = View.inflate(this, R.layout.view3, null);
 49         View view4 = View.inflate(this, R.layout.view4, null);
 50         viewList.add(view1);
 51         viewList.add(view2);
 52         viewList.add(view3);
 53         viewList.add(view4);
 54 
 55         // 第二种:通过Fragment作为viewPager的数据源
 56         fragmentlist = new ArrayList<Fragment>();
 57         fragmentlist.add(new Fragment1());
 58         fragmentlist.add(new Fragment2());
 59         fragmentlist.add(new Fragment3());
 60         fragmentlist.add(new Fragment4());
 61 
 62         // 为viewPager页卡设置标题
 63         titileList = new ArrayList<String>();
 64         titileList.add("第1页");
 65         titileList.add("第2页");
 66         titileList.add("第3页");
 67         titileList.add("第4页");
 68 
 69         // 为PagerTabStrip设置一些属性
 70         tap = (PagerTabStrip) findViewById(R.id.tap);
 71         tap.setBackgroundColor(Color.BLUE);
 72         tap.setTextColor(Color.RED);
 73         tap.setDrawFullUnderline(false);
 74         tap.setTabIndicatorColor(Color.GREEN);//小粗线颜色
 75 
 76         // 创建PagerAdapter适配器
 77         MyPagerAdapter adapter = new MyPagerAdapter(viewList, titileList);
 78         // viewPager加载适配器
 79         // Pager.setAdapter(adapter);
 80 
 81         MyFragmentPagerAdapter adapter2 = new MyFragmentPagerAdapter(
 82                 getSupportFragmentManager(), fragmentlist, titileList);
 83         // Pager.setAdapter(adapter2);
 84 
 85         // 如果ViewPager比较少的话,可以使用 FragmentPagerAdapter。另外还有
 86         // FragmentStatePagerAdapter,拥有动态销毁的功能。
 87         MyFragmentStatePagerAdapter adapter3 = new MyFragmentStatePagerAdapter(
 88                 getSupportFragmentManager(), fragmentlist, titileList);
 89         Pager.setAdapter(adapter3);
 90         
 91         
 92         Pager.setOnPageChangeListener(this);
 93 
 94     }
 95 
 96     @Override
 97     public void onPageScrollStateChanged(int arg0) {
 98         // TODO Auto-generated method stub
 99         
100     }
101 
102     @Override
103     public void onPageScrolled(int arg0, float arg1, int arg2) {
104         // TODO Auto-generated method stub
105         
106     }
107 
108     @Override
109     public void onPageSelected(int arg0) {
110         // TODO Auto-generated method stub
111         Toast.makeText(this, "当前是第"+(arg0+1)+"个页面", 1).show();
112     }
113 
114 }
//-----------------PagerAdapter------------------------------
 1 public class MyPagerAdapter extends PagerAdapter {
 2     //自己维护页卡的创建和销毁-只加载三个页卡
 3     private List<View> viewlist;
 4     private List<String> titileList;
 5 
 6     public MyPagerAdapter(List<View> viewlist, List<String> titileList) {
 7         // TODO Auto-generated constructor stub
 8         this.viewlist = viewlist;
 9         this.titileList = titileList;
10     }
11 
12     // 返回的是页卡数量
13     @Override
14     public int getCount() {
15         // TODO Auto-generated method stub
16         return viewlist.size();
17     }
18 
19     // 判断view是否来自对象
20     @Override
21     public boolean isViewFromObject(View arg0, Object arg1) {
22         // TODO Auto-generated method stub
23         return arg0 == arg1;
24     }
25 
26     // 实例化一个页卡
27     @Override
28     public Object instantiateItem(ViewGroup container, int position) {
29         // TODO Auto-generated method stub
30         container.addView(viewlist.get(position));
31         return viewlist.get(position);
32 
33     }
34 
35     // 销毁页卡
36     @Override
37     public void destroyItem(ViewGroup container, int position, Object object) {
38         // TODO Auto-generated method stub
39         container.removeView(viewlist.get(position));
40     }
41 
42     // 设置viewPager页卡的标题
43     @Override
44     public CharSequence getPageTitle(int position) {
45         // TODO Auto-generated method stub
46         return titileList.get(position);
47     }
48 }


适配器FragmentPagerAdaper

1. 创建 Fragment1~Fragment4,都继承 Fragment,重写onCreateView(),分别使用 inflater.inflate(R.layout.viewX,container,false);将布局文件 viewX.xml(X=1~4)转变为View对象。
2. 在 MainActivity创建 List<Fragment> fragList; 作为ViewPager的数据源。
3. 初始化 fragment 并添加 Fragment 对象:
fragList = new ArrayList<Fragment>();
        fragList.add(new Fragment1());
        fragList.add(new Fragment2());
        fragList.add(new Fragment3());
        fragList.add(new Fragment4());
注意 add() 里面是直接新建了 Fragment 对象。
4. 创建 FragmentPagerAdapter 适配器:创建一个类 MyFragmentPagerAdapter ,继承FragmentPagerAdapter。
重写构造方法(如图),使之可以传递参数。
5. 创建适配器。在MainActivity中创建适配器 MyFragmentPagerAdapter 的对象 adapter2。MyFragmentPagerAdapter()需要传递3个参数:
第一个参数是 FragmentManager ,我们需要让 MainActivity继承 FragmentActivity,然后第一个参写做 getSupportFragmentManager();
第二个参数:fragList;
第三个参数:titleList;
6. ViewPager加载适配器 pager.setAdapter(adapter2);

FragmentPagerAdapter 不像 PagerAdapter 那样三个三个地加载页面,而是一次性全部加载,所以不需要构建页卡和销毁页卡。所以,如果ViewPager比较少的话,可以使用 FragmentPagerAdapter。另外还有 FragmentStatePagerAdapter,拥有动态销毁的功能。

四个my
Fragment继承fragment分别加载view,主activity 继承FragmentActivity
public class Fragment1 extends android.support.v4.app.Fragment {

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        return inflater.inflate(R.layout.view1, container, false);
    }
}

//-----------------fragmentPagerAdapter-----------------


 1 //所有页卡一起加载,不会销毁
 2 public class MyFragmentPagerAdapter extends FragmentPagerAdapter {
 3     private List<Fragment> fragList;
 4     private List<String> titleList;
 5 
 6     public MyFragmentPagerAdapter(FragmentManager fm, List<Fragment> fragList,
 7             List<String> titleList) {
 8         super(fm);
 9         // TODO Auto-generated constructor stub
10         this.fragList = fragList;
11         this.titleList = titleList;
12     }
13 
14     @Override
15     public Fragment getItem(int arg0) {
16         // TODO Auto-generated method stub
17         return fragList.get(arg0);
18     }
19 
20     @Override
21     public CharSequence getPageTitle(int position) {
22         // TODO Auto-generated method stub
23         return titleList.get(position);
24     }
25 
26     @Override
27     public int getCount() {
28         // TODO Auto-generated method stub
29         return fragList.size();
30     }
31 
32 }





--------------------------------------------------------- FragmentStatePagerAdapter的使用,观察页面动态销毁的效果。 1. 复制前面写好的MyFragmentpagerAdapter ,命名为 MyFragmentpagerAdapter2; 2. 将继承的父类改为FragmentStatePagerAdapter; 3. 添加两个重写方法:instantiateItem() 和 destroyItem(); 4. 在 Fragment4.java中重写onDestroy(): @Override public void onDestroy() { super.onDestroy(); Log.i("main", "Fragment4被销毁了"); } 5. 在 MainActivity中创建FragmentStatePagerAdapter适配器: MyFragmentPagerAdapter2 adapter3 = new MyFragmentPagerAdapter2(getSupportFragmentManager(),fragList,titleList); 6. ViewPager加载适配器 pager.setAdapter(adapter3);
 1 //自己维护页卡的创建和销毁-只加载三个页卡
 2 public class MyFragmentStatePagerAdapter extends FragmentStatePagerAdapter {
 3     private List<Fragment> fragList;
 4     private List<String> titleList;
 5 
 6     public MyFragmentStatePagerAdapter(FragmentManager fm, List<Fragment> fragList,
 7             List<String> titleList) {
 8         super(fm);
 9         // TODO Auto-generated constructor stub
10         this.fragList = fragList;
11         this.titleList = titleList;
12     }
13 
14     @Override
15     public Fragment getItem(int arg0) {
16         // TODO Auto-generated method stub
17         return fragList.get(arg0);
18     }
19 
20     @Override
21     public CharSequence getPageTitle(int position) {
22         // TODO Auto-generated method stub
23         return titleList.get(position);
24     }
25 
26     @Override
27     public int getCount() {
28         // TODO Auto-generated method stub
29         return fragList.size();
30     }
31 
32     @Override
33     public Object instantiateItem(ViewGroup arg0, int arg1) {
34         // TODO Auto-generated method stub
35         return super.instantiateItem(arg0, arg1);
36     }
37 
38     @Override
39     public void destroyItem(ViewGroup container, int position, Object object) {
40         // TODO Auto-generated method stub
41         super.destroyItem(container, position, object);
42     }
43 }






监听器的使用
1. mainActivity实现接口 OnPageChangeListener,并重写3个方法。
2. 3个方法相对重要的是 onPageSelected(int position),这里只重写它,主要是返回当前页面的位置:
@Override
    public void onPageSelected(int position) {
        Toast.makeText(this, "当前是第"+(position+1)+"个页面 ", Toast.LENGTH_SHORT).show();//注意:position是从0开始计算的。
    }
3. ViewPager加载监听器
pager.setOnPageChangeListener(this);
实际工作中,经常使用ViewPager+Fragment的形式,因为Fragment的生命周期是比较全面的。而不使用ViewPager+View,因为View的创建和销毁的逻辑过程没有像Fragment那么好控制。
如果只是图方便,只是做展示,没有太多事务处理的话,可以使用View。
如果业务逻辑比较复杂,推荐使用 ViewPager+Fragment 组合。
 
 






原文地址:https://www.cnblogs.com/my334420/p/6714408.html