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

一、什么是ViewPager

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

 <?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="match_parent"
android:orientation="vertical"
android:gravity="center" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="我是第一个界面"
android:textSize="30sp"/> </LinearLayout>

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

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

 <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.support.v4.view.ViewPager
android:id="@+id/view_pager"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
> </android.support.v4.view.ViewPager> </LinearLayout>

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

 package com.example.viewpager;

 import java.util.List;

 import android.support.v4.view.PagerAdapter;
import android.view.View;
import android.view.ViewGroup;
/**
* ViewPager的适配器
* @author fuly1314
*
*/
public class ViewAdapter extends PagerAdapter{ private List<View> viewList;//数据源 public ViewAdapter(List<View> viewList){ this.viewList = viewList;
} //数据源的数目
public int getCount() { return viewList.size();
} //view是否由对象产生,官方写arg0==arg1即可
public boolean isViewFromObject(View arg0, Object arg1) { return arg0==arg1; } //销毁一个页卡(即ViewPager的一个item)
public void destroyItem(ViewGroup container, int position, Object object) { container.removeView(viewList.get(position));
} //对应页卡添加上数据
public Object instantiateItem(ViewGroup container, int position) { container.addView(viewList.get(position));//千万别忘记添加到container
return viewList.get(position);
} }

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

 package com.example.viewpager;

 import java.util.ArrayList;
import java.util.List; import android.os.Bundle;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.app.Activity; public class MainActivity extends Activity { private ViewPager pager;
private List<View> viewList = new ArrayList<View>();
private PagerAdapter viewAdapter; private LayoutInflater inflater; protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); //获取ViewPager
pager = (ViewPager) findViewById(R.id.view_pager); inflater = LayoutInflater.from(this); //获取四个view
View view1 = inflater.inflate(R.layout.layout1, null);
View view2 = inflater.inflate(R.layout.layout2, null);
View view3 = inflater.inflate(R.layout.layout3, null);
View view4 = inflater.inflate(R.layout.layout4, null); //将四个View加入到集合
viewList.add(view1);
viewList.add(view2);
viewList.add(view3);
viewList.add(view4); //实例化适配器
viewAdapter = new ViewAdapter(viewList); //设置适配器
pager.setAdapter(viewAdapter);
} }

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

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

(1)给ViewPager加标题

怎么加标题,基础知识里已经讲了,那么就先修改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.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> </LinearLayout>

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

 package com.example.viewpager;

 import java.util.List;

 import android.support.v4.view.PagerAdapter;
import android.view.View;
import android.view.ViewGroup;
/**
* ViewPager的适配器
* @author fuly1314
*
*/
public class ViewAdapter extends PagerAdapter{ private List<View> viewList;//数据源
private List<String> titles;//标题 public ViewAdapter(List<View> viewList,List<String> titles){ this.viewList = viewList;
this.titles = titles;
} //数据源的数目
public int getCount() { return viewList.size();
} //view是否由对象产生,官方写arg0==arg1即可
public boolean isViewFromObject(View arg0, Object arg1) { return arg0==arg1; } //销毁一个页卡(即ViewPager的一个item)
public void destroyItem(ViewGroup container, int position, Object object) { container.removeView(viewList.get(position));
} //对应页卡添加上数据
public Object instantiateItem(ViewGroup container, int position) { container.addView(viewList.get(position));//千万别忘记添加到container
return viewList.get(position);
} 53 //为对应的页卡设置标题
54 public CharSequence getPageTitle(int position) {
55
56 return titles.get(position);
57 } }

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

 package com.example.viewpager;

 import java.util.ArrayList;
import java.util.List; 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.app.Activity;
import android.graphics.Color; public class MainActivity extends Activity { private ViewPager pager;
private List<View> viewList = new ArrayList<View>();//数据源
private PagerAdapter viewAdapter; private List<String> titles = new ArrayList<String>();//标题 private LayoutInflater inflater; private PagerTabStrip pagerTitle;//ViewPager的标题
28 protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); //获取ViewPager
pager = (ViewPager) findViewById(R.id.view_pager); //添加标题
47 titles.add("第一页");
48 titles.add("第二页");
49 titles.add("第三页");
50 titles.add("第四页"); inflater = LayoutInflater.from(this); //获取四个view
View view1 = inflater.inflate(R.layout.layout1, null);
View view2 = inflater.inflate(R.layout.layout2, null);
View view3 = inflater.inflate(R.layout.layout3, null);
View view4 = inflater.inflate(R.layout.layout4, null); //将四个View加入到集合
viewList.add(view1);
viewList.add(view2);
viewList.add(view3);
viewList.add(view4); //实例化适配器
viewAdapter = new ViewAdapter(viewList,titles); //设置适配器
pager.setAdapter(viewAdapter);
} }

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

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

 package com.example.viewpager;

 import java.util.ArrayList;
import java.util.List; 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.app.Activity;
import android.graphics.Color; public class MainActivity extends Activity { private ViewPager pager;
private List<View> viewList = new ArrayList<View>();//数据源
private PagerAdapter viewAdapter; private List<String> titles = new ArrayList<String>();//标题 private LayoutInflater inflater; private PagerTabStrip pagerTitle;//ViewPager的标题 protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); 3 //获取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);//设置标题下粗一点的短分割线的颜色 //添加标题
titles.add("第一页");
titles.add("第二页");
titles.add("第三页");
titles.add("第四页"); inflater = LayoutInflater.from(this); //获取四个view
View view1 = inflater.inflate(R.layout.layout1, null);
View view2 = inflater.inflate(R.layout.layout2, null);
View view3 = inflater.inflate(R.layout.layout3, null);
View view4 = inflater.inflate(R.layout.layout4, null); //将四个View加入到集合
viewList.add(view1);
viewList.add(view2);
viewList.add(view3);
viewList.add(view4); //实例化适配器
viewAdapter = new ViewAdapter(viewList,titles); //设置适配器
pager.setAdapter(viewAdapter);
} }

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

终于实现了我们一开始展示的效果了。有必要小结一下,为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中的代码如下:

 package com.example.viewpager;

 import java.util.ArrayList;
import java.util.List; import android.os.Bundle;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.PagerTabStrip;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Toast;
import android.app.Activity;
import android.graphics.Color; public class MainActivity extends Activity implements OnPageChangeListener{ private ViewPager pager;
private List<View> viewList = new ArrayList<View>();//数据源
private PagerAdapter viewAdapter; private List<String> titles = new ArrayList<String>();//标题 private LayoutInflater inflater; private PagerTabStrip pagerTitle; protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); //获取ViewPager
pager = (ViewPager) findViewById(R.id.view_pager); pager.setOnPageChangeListener(this);//设置监听器 //获取pagerTitle
pagerTitle = (PagerTabStrip) findViewById(R.id.pager_title); //为标题设置属性,比如背景,颜色线等
pagerTitle.setBackgroundColor(Color.RED);//设置背景颜色
pagerTitle.setTextColor(Color.YELLOW);//设置标题文字的颜色
pagerTitle.setDrawFullUnderline(false);//将标题下的长分割线去掉
pagerTitle.setTabIndicatorColor(Color.BLUE);//设置标题下粗一点的短分割线的颜色 //添加标题
titles.add("第一页");
titles.add("第二页");
titles.add("第三页");
titles.add("第四页"); inflater = LayoutInflater.from(this); //获取四个view
View view1 = inflater.inflate(R.layout.layout1, null);
View view2 = inflater.inflate(R.layout.layout2, null);
View view3 = inflater.inflate(R.layout.layout3, null);
View view4 = inflater.inflate(R.layout.layout4, null); //将四个View加入到集合
viewList.add(view1);
viewList.add(view2);
viewList.add(view3);
viewList.add(view4); //实例化适配器
viewAdapter = new ViewAdapter(viewList,titles); //设置适配器
pager.setAdapter(viewAdapter);
} //当滚动状态改变时被调用
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 }

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

使用View填充ViewPager的更多相关文章

  1. 使用Fragment填充ViewPager

    在上一篇文章中,讲解了使用PagerAdapter作为适配器时的ViewPager的使用方法.然后在实际项目中更多的使用Fragment作为页卡,因为实际开发中每一个页卡要复杂的多.而使用Fragme ...

  2. Android——ViewPager滑动背景渐变(自定义view,ViewPager)

    效果: ActivityBackgroundImage,java(自定义视图) package com.example.chenshuai.test322; import android.conten ...

  3. Android自定义View——自定义ViewPager

      第一部分:自定义ViewGroup的使用,手势识别器和Scroller滑动 第二部分:处理滑动监听,处理滑动冲突,增加ViewPager的指示器   常见的滑动冲突:外部滑动方向和内部滑动方向不一 ...

  4. Android开发之ViewPager实现轮播图(轮播广告)效果的自定义View

    最近开发中需要做一个类似京东首页那样的广告轮播效果,于是采用ViewPager自己自定义了一个轮播图效果的View. 主要原理就是利用定时任务器定时切换ViewPager的页面. 效果图如下: 主页面 ...

  5. ViewPagerWithViewDemo【ViewPager和View搭配以及演示获取里面的值和CheckBox单选效果】

    版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 简单记录下ViewPager和自定义布局view的搭配使用以及布局文件中单选效果.获取viewpager布局内部值的功能. 效果图 ...

  6. viewpager与子view的事件冲突解决

    问题: 对android的事件机制一直不怎么了解,最近android项目中运用viewpager+listview (就是viewpager的子view中嵌套了listview),出现了触摸手势冲突 ...

  7. ViewPager的简单使用

    1.布局文件 a.主布局文件 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xml ...

  8. Android ViewPager使用详解

    这是谷歌官方给我们提供的一个兼容低版本安卓设备的软件包,里面包囊了只有在安卓3.0以上可以使用的api.而viewpager就是其中之一利用它,我们可以做很多事情,从最简单的导航,到页面菜单等等.那如 ...

  9. ViewFlipper、ViewPager和Gallery

    1.ViewFlipper 1)View切换的控件—ViewFlipper介绍 ViewFilpper类继承于ViewAnimator类.而ViewAnimator类继承于FrameLayout. 查 ...

随机推荐

  1. <数据挖掘导论>读书笔记5关联分析的基本概念和算法

    关联规则的强度可以用support度和confidence(置信)度来度量 关联规则发现  给定事务的集合T,关联规则发现是指找出支持度大于等于minsup并且置信度大于等于minconf的所有规则, ...

  2. weblogic cluster error-----Could not= open connection with host: 127.0.0.1

    weblogic主机及一台从机启动成功后,在启动从机的时候报错, <BEA-000905> <Could not open connection with host: 127.0.0 ...

  3. linq——常用方法

    take  前几 skip   跳过前几 takeWhile   var firstNumbersLessThan6 = numbers.TakeWhile(n => n < 6);  / ...

  4. Nexus-NuGet私有仓库服务搭建(一)

    搭建私有Nuget服务器的方式有很多,大多数人文章介绍在vs 中新建默认web项目,然后再Nuget 中安装 Nuget.Server,再部署到IIS 中即可.虽然能用,但是这种方式太过简陋,操作界面 ...

  5. Java Netty简介

    Netty和Mina是Java世界非常知名的通讯框架.它们都出自同一个作者,Mina诞生略早,属于Apache基金会,而Netty开始在Jboss名下,后来出来自立门户netty.io(http:// ...

  6. Redis 常见命令

    0. 5种数据类型 String(字符串) List(列表) Hash(字典) Set(集合) Sorted Set(有序集合) 1. String 字符串 set key value 设置key=v ...

  7. 网站大于10M的视频不能播放

    IIS配置的网站,添加了几个mp4视频,有个可以正常播放,有的却不加载不出来,提示错误: net::ERR_CONNECTION_ABORTED 网上有文章说是由于安全狗bug导致,下载安装一个补丁覆 ...

  8. svn怎么下载代码到本地

    1. 在我们安装好svn时,在指定的目录中点击鼠标右键SVN Checkout,弹出以下窗口.(在文件夹下各自建好前后台的文件夹分别check) 2. 在URL of repository:(存储库的 ...

  9. php从身份证获取性别和出生年月

    //通过身份证号查询出性别与生日 $birth = strlen($idcard)==15 ? ('19' . substr($idcard, 6, 6)) : substr($idcard, 6, ...

  10. ccf-201809-2 买菜

    问题描述 小H和小W来到了一条街上,两人分开买菜,他们买菜的过程可以描述为,去店里买一些菜然后去旁边的一个广场把菜装上车,两人都要买n种菜,所以也都要装n次车.具体的,对于小H来说有n个不相交的时间段 ...