zoukankan      html  css  js  c++  java
  • 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 组合。
     
     






  • 相关阅读:
    SQLite学习手册(锁和并发控制)
    SQLite学习手册(命令行工具)
    SQLite学习手册(表达式)
    SQLite学习手册(内存数据库)
    SQLite学习手册(在线备份)
    SQLite学习手册(索引和数据分析/清理)
    SQLite学习手册(临时文件)
    随笔之正则表达式
    序列化,反序列化方法
    小东西,点击按钮防连击
  • 原文地址:https://www.cnblogs.com/my334420/p/6714408.html
Copyright © 2011-2022 走看看