转载

使用View作为填充ViewPager

ViewPager在app开发中十分常见。今天以一个例子详细解读下ViewPager的基础知识。

一、什么是ViewPager

可以这样理解,ViewPager就相当于一个容器,它的里面可以装view作为页面,也可以装Fragment作为页面。例如常用的微信主界面,就可以用ViewPager做出那样的效果。下面是一个直观的效果图,相信你看了,就会明白什么是ViewPager。

使用View作为填充ViewPager

效果说明:在模拟器用的是鼠标,在手机上用的就应该是手指来滑动了, 总之就是左右滑动,会出现不同的界面 。想想微信主界面是不是左右滑动,就会展现不同的界面呢?道理是一样的。

我们先将基础知识给总结一下,然后再来实现这样子的效果,这样也好看得懂下面的代码。

二、关于ViewPager的基础知识

这些基础知识并不难。都是很简单的,总结如下:

在布局中加入ViewPager:   <android.support.v4.view.ViewPager     android:id="@+id/view_pager"     android:layout_width="wrap_content"     android:layout_height="wrap_content"     >              </android.support.v4.view.ViewPager>  在布局总加入带标题的ViewPager:  <android.support.v4.view.ViewPager            android:id="@+id/view_pager"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            >            <android.support.v4.view.PagerTabStrip                                android:id="@+id/pager_title"                android:layout_width="wrap_content"                 android:layout_height="wrap_content">                            </android.support.v4.view.PagerTabStrip>              </android.support.v4.view.ViewPager>  ViewPager的监听器: 即是OnPageChangeListener。实现这个监听接口,必须重写三个方法,一般我们比较关注的是onPageSelected方法(当页卡被选中时会调用)。 ViewPager的适配器也有几种: (1)PagerAdapter:数据源是view,即向ViewPager中填充view作为页卡。 (1)FragmentPagerAdapter:数据源是Fragment,即Fragment作为页卡。 (3)FragmentStatePagerAdapter:同样是Fragment作为页卡。 注意,FragmentPagerAdapter是一次性将所有页卡都加载完毕,没有销毁的。而FragmentStatePagerAdapter并不是一次性将页卡都加载完毕,而是默认每次加载进三个页卡,当前页卡被滑动消失就会被销毁。这是它们的区别。因此如果页卡较多,建议采用FragmentStatePagerAdapter适配器。  

好了,有了上面的基础知识,下面就可以看看具体的实现了。毕竟不看代码,没法说清楚ViewPager是怎么用的。下面会一步一步实现出本文开头的效果出来。

三、实际例子

新建项目,然后新建布局layout1.xml。其中的代码如下:

1 <?xml version="1.0" encoding="utf-8"?>  2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  3     android:layout_width="match_parent"  4     android:layout_height="match_parent"  5     android:orientation="vertical"  6     android:gravity="center" >  7     <TextView  8         android:layout_width="wrap_content"  9         android:layout_height="wrap_content" 10         android:text="我是第一个界面" 11         android:textSize="30sp"/> 12  13 </LinearLayout>

然后这样的布局再建立三个,分别命名为alyout2.xml,layout3.xml,layout4.xml。每一个布局只是将第10行的文本显示改了,改为“我是第二个界面”,“我是第三个界面”,“我是第四个界面”。这样子,要装进ViewPager里的布局文件我们就写好了。

然后修改activity_main.xml中的代码,将ViewPager放进里面。代码如下:

1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  2     xmlns:tools="http://schemas.android.com/tools"  3     android:layout_width="match_parent"  4     android:layout_height="match_parent"  5        >  6        <android.support.v4.view.ViewPager  7            android:id="@+id/view_pager"  8            android:layout_width="wrap_content"  9            android:layout_height="wrap_content" 10            > 11             12        </android.support.v4.view.ViewPager> 13  14    15  16 </LinearLayout>

接着为ViewPager写适配器,因为要填充的是view,所以用PagerAdapter作为适配器,新建类ViewAdapter继承它即可。代码如下:

1 package com.example.viewpager;  2   3 import java.util.List;  4   5 import android.support.v4.view.PagerAdapter;  6 import android.view.View;  7 import android.view.ViewGroup;  8 /**  9  * ViewPager的适配器 10  * @author fuly1314 11  * 12  */ 13 public class ViewAdapter extends PagerAdapter{ 14  15     private List<View> viewList;//数据源 16      17     public ViewAdapter(List<View> viewList){ 18          19         this.viewList = viewList; 20     } 21      22     //数据源的数目 23     public int getCount() { 24  25         return viewList.size(); 26     } 27  28  29     //view是否由对象产生,官方写arg0==arg1即可 30     public boolean isViewFromObject(View arg0, Object arg1) { 31          32         return arg0==arg1; 33          34     } 35  36  37     //销毁一个页卡(即ViewPager的一个item) 38     public void destroyItem(ViewGroup container, int position, Object object) { 39          40         container.removeView(viewList.get(position)); 41     } 42  43  44     //对应页卡添加上数据 45     public Object instantiateItem(ViewGroup container, int position) { 46  47         container.addView(viewList.get(position));//千万别忘记添加到container 48         return viewList.get(position); 49     } 50      51  52 }

从适配器上,可以看出,PagerView是具有销毁页卡的属性的。 其实它每次加载3个页卡,即当前显示的页卡以及其前后的页卡都被加载进来。 然后我们再修改MainActivity中的代码,将这些都组合到一起即可。如下:

1 package com.example.viewpager;  2   3 import java.util.ArrayList;  4 import java.util.List;  5   6 import android.os.Bundle;  7 import android.support.v4.view.PagerAdapter;  8 import android.support.v4.view.ViewPager;  9 import android.view.LayoutInflater; 10 import android.view.View; 11 import android.app.Activity; 12  13 public class MainActivity extends Activity { 14      15     private ViewPager pager; 16     private List<View> viewList = new ArrayList<View>(); 17     private PagerAdapter viewAdapter; 18      19      20      21     private LayoutInflater inflater; 22      23  24     protected void onCreate(Bundle savedInstanceState) { 25         super.onCreate(savedInstanceState); 26         setContentView(R.layout.activity_main); 27          28         //获取ViewPager 29         pager = (ViewPager) findViewById(R.id.view_pager); 30          31         inflater = LayoutInflater.from(this); 32          33         //获取四个view 34         View view1 = inflater.inflate(R.layout.layout1, null); 35         View view2 = inflater.inflate(R.layout.layout2, null); 36         View view3 = inflater.inflate(R.layout.layout3, null); 37         View view4 = inflater.inflate(R.layout.layout4, null); 38          39         //将四个View加入到集合 40         viewList.add(view1); 41         viewList.add(view2); 42         viewList.add(view3); 43         viewList.add(view4); 44          45         //实例化适配器 46         viewAdapter = new ViewAdapter(viewList); 47          48         //设置适配器 49         pager.setAdapter(viewAdapter); 50     } 51  52      53 }

好了,多搞定了,然后我们运行程序,效果如下:

使用View作为填充ViewPager

我们左右滑动,就会呈现不同的视图。但是跟上面的效果好像不太一样,那是因为我们没有给它加上标题。下面咱就来给它加上标题。

(1)给ViewPager加标题

怎么加标题,基础知识里已经讲了,那么就先修改activity_main.xml,把标题加上。代码如下:

1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  2     xmlns:tools="http://schemas.android.com/tools"  3     android:layout_width="match_parent"  4     android:layout_height="match_parent"  5        >  6        <android.support.v4.view.ViewPager  7            android:id="@+id/view_pager"  8            android:layout_width="wrap_content"  9            android:layout_height="wrap_content" 10            > 11            <android.support.v4.view.PagerTabStrip 12                 13                android:id="@+id/pager_title" 14                android:layout_width="wrap_content" 15                 android:layout_height="wrap_content"> 16                 17            </android.support.v4.view.PagerTabStrip> 18             19        </android.support.v4.view.ViewPager> 20  21    22  23 </LinearLayout>

需要说明的是,PagerTabStrip是ViewPager的一个子标签,一定要加载ViewPager内部。 然后再修改适配器,让标题适配,如下:

1 package com.example.viewpager;  2   3 import java.util.List;  4   5 import android.support.v4.view.PagerAdapter;  6 import android.view.View;  7 import android.view.ViewGroup;  8 /**  9  * ViewPager的适配器 10  * @author fuly1314 11  * 12  */ 13 public class ViewAdapter extends PagerAdapter{ 14  15     private List<View> viewList;//数据源 16     private List<String> titles;//标题 17      18     public ViewAdapter(List<View> viewList,List<String> titles){ 19          20         this.viewList = viewList; 21         this.titles = titles; 22     } 23      24     //数据源的数目 25     public int getCount() { 26  27         return viewList.size(); 28     } 29  30  31     //view是否由对象产生,官方写arg0==arg1即可 32     public boolean isViewFromObject(View arg0, Object arg1) { 33          34         return arg0==arg1; 35          36     } 37  38  39     //销毁一个页卡(即ViewPager的一个item) 40     public void destroyItem(ViewGroup container, int position, Object object) { 41          42         container.removeView(viewList.get(position)); 43     } 44  45  46     //对应页卡添加上数据 47     public Object instantiateItem(ViewGroup container, int position) { 48  49         container.addView(viewList.get(position));//千万别忘记添加到container 50         return viewList.get(position); 51     } 52  53     //为对应的页卡设置标题 54     public CharSequence getPageTitle(int position) { 55          56         return titles.get(position); 57     } 58      59  60 }

注意红色部分,即第53行到第57行,就是给相应的页卡适配上相应的标题。最后就是在MainActivity中,将标题数据源建立出来,然后传入到适配器即可。代码如下:

1 package com.example.viewpager;  2   3 import java.util.ArrayList;  4 import java.util.List;  5   6 import android.os.Bundle;  7 import android.support.v4.view.PagerAdapter;  8 import android.support.v4.view.PagerTabStrip;  9 import android.support.v4.view.ViewPager; 10 import android.view.LayoutInflater; 11 import android.view.View; 12 import android.app.Activity; 13 import android.graphics.Color; 14  15 public class MainActivity extends Activity { 16      17     private ViewPager pager; 18     private List<View> viewList = new ArrayList<View>();//数据源 19     private PagerAdapter viewAdapter; 20      21     private List<String> titles = new ArrayList<String>();//标题 22      23      24      25     private LayoutInflater inflater; 26      27     private PagerTabStrip pagerTitle;//ViewPager的标题 28      29  30     protected void onCreate(Bundle savedInstanceState) { 31         super.onCreate(savedInstanceState); 32         setContentView(R.layout.activity_main); 33          34         //获取ViewPager 35         pager = (ViewPager) findViewById(R.id.view_pager); 36          45          46         //添加标题 47         titles.add("第一页"); 48         titles.add("第二页"); 49         titles.add("第三页"); 50         titles.add("第四页"); 51          52          53          54          55         inflater = LayoutInflater.from(this); 56          57         //获取四个view 58         View view1 = inflater.inflate(R.layout.layout1, null); 59         View view2 = inflater.inflate(R.layout.layout2, null); 60         View view3 = inflater.inflate(R.layout.layout3, null); 61         View view4 = inflater.inflate(R.layout.layout4, null); 62          63         //将四个View加入到集合 64         viewList.add(view1); 65         viewList.add(view2); 66         viewList.add(view3); 67         viewList.add(view4); 68          69         //实例化适配器 70         viewAdapter = new ViewAdapter(viewList,titles); 71          72         //设置适配器 73         pager.setAdapter(viewAdapter); 74     } 75  76      77 }

红色部分就是为添加标题,所增添的代码。然后我们运行一下程序,再来看看效果:

使用View作为填充ViewPager

怎么样,标题如愿已经加上了。如果此时你觉得不是很美观,那么可以继续给标题设定一个属性。比如我们上面的标题的效果,就是这样子设定的,修改MainActivity中的代码,如下:

1 package com.example.viewpager;  2   3 import java.util.ArrayList;  4 import java.util.List;  5   6 import android.os.Bundle;  7 import android.support.v4.view.PagerAdapter;  8 import android.support.v4.view.PagerTabStrip;  9 import android.support.v4.view.ViewPager; 10 import android.view.LayoutInflater; 11 import android.view.View; 12 import android.app.Activity; 13 import android.graphics.Color; 14  15 public class MainActivity extends Activity { 16      17     private ViewPager pager; 18     private List<View> viewList = new ArrayList<View>();//数据源 19     private PagerAdapter viewAdapter; 20      21     private List<String> titles = new ArrayList<String>();//标题 22      23      24      25     private LayoutInflater inflater; 26      27     private PagerTabStrip pagerTitle;//ViewPager的标题 28      29  30     protected void onCreate(Bundle savedInstanceState) { 31         super.onCreate(savedInstanceState); 32         setContentView(R.layout.activity_main); 33          34         //获取ViewPager 35         pager = (ViewPager) findViewById(R.id.view_pager); 36          37         //获取pagerTitle 38         pagerTitle = (PagerTabStrip) findViewById(R.id.pager_title); 39          40         //为标题设置属性,比如背景,颜色线等 41         pagerTitle.setBackgroundColor(Color.RED);//设置背景颜色 42         pagerTitle.setTextColor(Color.YELLOW);//设置标题文字的颜色 43         pagerTitle.setDrawFullUnderline(false);//将标题下的长分割线去掉 44         pagerTitle.setTabIndicatorColor(Color.BLUE);//设置标题下粗一点的短分割线的颜色 45          46         //添加标题 47         titles.add("第一页"); 48         titles.add("第二页"); 49         titles.add("第三页"); 50         titles.add("第四页"); 51          52          53          54          55         inflater = LayoutInflater.from(this); 56          57         //获取四个view 58         View view1 = inflater.inflate(R.layout.layout1, null); 59         View view2 = inflater.inflate(R.layout.layout2, null); 60         View view3 = inflater.inflate(R.layout.layout3, null); 61         View view4 = inflater.inflate(R.layout.layout4, null); 62          63         //将四个View加入到集合 64         viewList.add(view1); 65         viewList.add(view2); 66         viewList.add(view3); 67         viewList.add(view4); 68          69         //实例化适配器 70         viewAdapter = new ViewAdapter(viewList,titles); 71          72         //设置适配器 73         pager.setAdapter(viewAdapter); 74     } 75  76      77 }

注意红色部分的代码,就是为标题设定的一些属性。然后再运行程序,效果图如下:

使用View作为填充ViewPager

终于实现了我们一开始展示的效果了。有必要小结一下,为 ViewPager的标题设置属性:

为ViewPager的标题设置属性: //获取pagerTitle  pagerTitle = (PagerTabStrip) findViewById(R.id.pager_title);   //为标题设置属性,比如背景,颜色线等    pagerTitle.setBackgroundColor(Color.RED);//设置背景颜色    pagerTitle.setTextColor(Color.YELLOW);//设置标题文字的颜色    pagerTitle.setDrawFullUnderline(false);//将标题下的长分割线去掉    pagerTitle.setTabIndicatorColor(Color.BLUE);//设置标题下粗一点的短分割线的颜色 

(2)为ViewPager设置监听器

为了说明OnPagerChangeListener到底是怎么用的,在此简单的让滑动页卡的时候弹出个提示吧。修改MainActivity中的代码如下:

1 package com.example.viewpager;   2    3 import java.util.ArrayList;   4 import java.util.List;   5    6 import android.os.Bundle;   7 import android.support.v4.view.PagerAdapter;   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.view.LayoutInflater;  12 import android.view.View;  13 import android.widget.Toast;  14 import android.app.Activity;  15 import android.graphics.Color;  16   17 public class MainActivity extends Activity implements OnPageChangeListener{  18       19     private ViewPager pager;  20     private List<View> viewList = new ArrayList<View>();//数据源  21     private PagerAdapter viewAdapter;  22       23     private List<String> titles = new ArrayList<String>();//标题  24       25       26       27     private LayoutInflater inflater;  28       29     private PagerTabStrip pagerTitle;  30       31   32     protected void onCreate(Bundle savedInstanceState) {  33         super.onCreate(savedInstanceState);  34         setContentView(R.layout.activity_main);  35           36         //获取ViewPager  37         pager = (ViewPager) findViewById(R.id.view_pager);  38           39         pager.setOnPageChangeListener(this);//设置监听器  40           41         //获取pagerTitle  42         pagerTitle = (PagerTabStrip) findViewById(R.id.pager_title);  43           44         //为标题设置属性,比如背景,颜色线等  45         pagerTitle.setBackgroundColor(Color.RED);//设置背景颜色  46         pagerTitle.setTextColor(Color.YELLOW);//设置标题文字的颜色  47         pagerTitle.setDrawFullUnderline(false);//将标题下的长分割线去掉  48         pagerTitle.setTabIndicatorColor(Color.BLUE);//设置标题下粗一点的短分割线的颜色  49           50         //添加标题  51         titles.add("第一页");  52         titles.add("第二页");  53         titles.add("第三页");  54         titles.add("第四页");  55           56           57           58           59         inflater = LayoutInflater.from(this);  60           61         //获取四个view  62         View view1 = inflater.inflate(R.layout.layout1, null);  63         View view2 = inflater.inflate(R.layout.layout2, null);  64         View view3 = inflater.inflate(R.layout.layout3, null);  65         View view4 = inflater.inflate(R.layout.layout4, null);  66           67         //将四个View加入到集合  68         viewList.add(view1);  69         viewList.add(view2);  70         viewList.add(view3);  71         viewList.add(view4);  72           73         //实例化适配器  74         viewAdapter = new ViewAdapter(viewList,titles);  75           76         //设置适配器  77         pager.setAdapter(viewAdapter);  78     }  79   80   81   82     //当滚动状态改变时被调用  83     public void onPageScrollStateChanged(int arg0) {  84       85           86     }  87   88   89     //滚动时调用  90     public void onPageScrolled(int arg0, float arg1, int arg2) {  91       92           93     }  94   95   96     //当页卡被选中时调用  97     public void onPageSelected(int arg0) {  98           99         Toast.makeText(this, "这是第"+(arg0+1)+"个界面", Toast.LENGTH_LONG).show(); 100          101     } 102  103      104 }

红色部分就是设定监听器的代码,当页卡被调用时,简单的弹出一个提示框而已。运行效果如下:

使用View作为填充ViewPager

正文到此结束
Loading...