Android中的ViewPager使用详解

/

软硬件环境

  • Android studio 2.1.3
  • 坚果手机 5.1.1

前言

ViewPager是android中进行View切换的一个控件。它是一个使用率非常高的控件,像app初次使用时的引导页面。本文将来学习一下这个控件以及相关的一些内容。

ViewPager的使用

要使用ViewPager,一般需要进行如下步骤

  1. 主布局中加入ViewPager
  2. 确定切换子View的布局
  3. 重写PagerAdapter的几个方法
  4. 给ViewPager设置adapter

主布局layout_main.xml

MainActivity的布局文件,加入ViewPager控件

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. xmlns:tools="http://schemas.android.com/tools"
  4. android:layout_width="match_parent"
  5. android:layout_height="match_parent"
  6. tools:context="com.xugaoxiang.viewpagerdemo.MainActivity">
  7. <android.support.v4.view.ViewPager
  8. android:id="@+id/viewPager"
  9. android:layout_gravity="center"
  10. android:layout_width="match_parent"
  11. android:layout_height="match_parent">
  12. </android.support.v4.view.ViewPager>
  13. </LinearLayout>

layout_tab*.xml

子View的布局文件,只包含一个ImageView。我这里设置了5个切换的View,准备了5张美女图片,其它几个子View的布局跟这个差不多,只有图片不一样,这里就不再写了,自己补全吧。

  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. <ImageView
  6. android:src="@drawable/beauty1"
  7. android:layout_width="match_parent"
  8. android:layout_height="match_parent" />
  9. </LinearLayout>

MainActivity.java文件

  1. package com.xugaoxiang.viewpagerdemo;
  2. import android.support.v4.view.PagerAdapter;
  3. import android.support.v4.view.ViewPager;
  4. import android.support.v7.app.AppCompatActivity;
  5. import android.os.Bundle;
  6. import android.view.LayoutInflater;
  7. import android.view.View;
  8. import android.view.ViewGroup;
  9. import java.util.ArrayList;
  10. import java.util.List;
  11. public class MainActivity extends AppCompatActivity {
  12. private ViewPager viewPager;
  13. private List<View> views;
  14. @Override
  15. protected void onCreate(Bundle savedInstanceState) {
  16. super.onCreate(savedInstanceState);
  17. setContentView(R.layout.activity_main);
  18. viewPager = (ViewPager) findViewById(R.id.viewPager);
  19. LayoutInflater layoutInflater = getLayoutInflater();
  20. views = new ArrayList<View>();
  21. views.add(layoutInflater.inflate(R.layout.layout_tab1,null));
  22. views.add(layoutInflater.inflate(R.layout.layout_tab2,null));
  23. views.add(layoutInflater.inflate(R.layout.layout_tab3,null));
  24. views.add(layoutInflater.inflate(R.layout.layout_tab4,null));
  25. views.add(layoutInflater.inflate(R.layout.layout_tab5,null));
  26. PagerAdapter pagerAdapter = new PagerAdapter() {
  27. @Override
  28. public int getCount() {
  29. return views.size();
  30. }
  31. @Override
  32. public boolean isViewFromObject(View view, Object object) {
  33. return view == object;
  34. }
  35. @Override
  36. public void destroyItem(ViewGroup container, int position, Object object) {
  37. // super.destroyItem(container, position, object);
  38. container.removeView(views.get(position));
  39. }
  40. @Override
  41. public Object instantiateItem(ViewGroup container, int position) {
  42. // return super.instantiateItem(container, position);
  43. container.addView(views.get(position));
  44. return views.get(position);
  45. }
  46. };
  47. viewPager.setAdapter(pagerAdapter);
  48. }
  49. }

初始化一个List用来存放需要切换的view,然后实例化PagerAdapter并重写getCount()、isViewFromObject()、destroyItem()和instantiateItem()这4个方法。运行下这个工程

viewpager_01

PagerAdapter中需要重写的几个函数

现在回头再看看PagerAdapter需要重写的4个方法

  • getCount 返回当前有效子view的个数
  • destroyItem 将制定的view从container中移除
  • instantiateItem 将视图添加到container中,并将当前视图作为key进行返回
  • isViewFromObject 判断instantiateItem方法返回来的key与视图是不是同一个

注意到上面方法解释中谈到了一个新的概念,key。简单来讲,key是视图的标识,根据key就可以找到其对应的view。在我们重写instantiateItem这个方法时,我们将View作为key返回,当然你也可以将position作为key进行返回。这样的话,对应地在重写isViewFromObject方法时,应该先根据position找到view再和参数1的View尽心比较,一致返回ture,否则返回false。

PagerTitleStrip和PagerTabStrip

PagerTitleStrip和PagerTabStrip都是用来实现标题栏的,它们的写法完全一样,区别在于

  1. PagerTabStrip方式的标题栏下有根下划线
  2. PagerTabStrip方式的标题栏响应点击事件,可以切换到对应的view

layout_mail.xml布局文件

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. xmlns:tools="http://schemas.android.com/tools"
  4. android:layout_width="match_parent"
  5. android:layout_height="match_parent"
  6. tools:context="com.xugaoxiang.viewpagerdemo.MainActivity">
  7. <android.support.v4.view.ViewPager
  8. android:id="@+id/viewPager"
  9. android:layout_gravity="center"
  10. android:layout_width="match_parent"
  11. android:layout_height="match_parent">
  12. <android.support.v4.view.PagerTitleStrip
  13. android:id="@+id/pagerTitle"
  14. android:layout_gravity="top"
  15. android:layout_width="wrap_content"
  16. android:layout_height="wrap_content">
  17. </android.support.v4.view.PagerTitleStrip>
  18. </android.support.v4.view.ViewPager>
  19. </LinearLayout>

属性android:layout_gravity=”top”指定了标题栏设置在了顶部,当然你也可以将它设置在底部。

MainActivity.java中实例化PagerAdapter时,需要再重写一个方法,getPageTitle

  1. package com.xugaoxiang.viewpagerdemo;
  2. import android.support.v4.view.PagerAdapter;
  3. import android.support.v4.view.ViewPager;
  4. import android.support.v7.app.AppCompatActivity;
  5. import android.os.Bundle;
  6. import android.view.LayoutInflater;
  7. import android.view.View;
  8. import android.view.ViewGroup;
  9. import java.util.ArrayList;
  10. import java.util.List;
  11. public class MainActivity extends AppCompatActivity {
  12. private ViewPager viewPager;
  13. private List<View> views;
  14. private List<String> titleList;
  15. @Override
  16. protected void onCreate(Bundle savedInstanceState) {
  17. super.onCreate(savedInstanceState);
  18. setContentView(R.layout.activity_main);
  19. viewPager = (ViewPager) findViewById(R.id.viewPager);
  20. LayoutInflater layoutInflater = getLayoutInflater();
  21. views = new ArrayList<View>();
  22. views.add(layoutInflater.inflate(R.layout.layout_tab1,null));
  23. views.add(layoutInflater.inflate(R.layout.layout_tab2,null));
  24. views.add(layoutInflater.inflate(R.layout.layout_tab3,null));
  25. views.add(layoutInflater.inflate(R.layout.layout_tab4,null));
  26. views.add(layoutInflater.inflate(R.layout.layout_tab5,null));
  27. titleList = new ArrayList<String>();
  28. titleList.add("第一页Tab");
  29. titleList.add("第二页Tab");
  30. titleList.add("第三页Tab");
  31. titleList.add("第四页Tab");
  32. titleList.add("第五页Tab");
  33. PagerAdapter pagerAdapter = new PagerAdapter() {
  34. @Override
  35. public int getCount() {
  36. return views.size();
  37. }
  38. @Override
  39. public boolean isViewFromObject(View view, Object object) {
  40. return view == object;
  41. }
  42. @Override
  43. public void destroyItem(ViewGroup container, int position, Object object) {
  44. // super.destroyItem(container, position, object);
  45. container.removeView(views.get(position));
  46. }
  47. @Override
  48. public Object instantiateItem(ViewGroup container, int position) {
  49. // return super.instantiateItem(container, position);
  50. container.addView(views.get(position));
  51. return views.get(position);
  52. }
  53. @Override
  54. public CharSequence getPageTitle(int position) {
  55. // return super.getPageTitle(position);
  56. return titleList.get(position);
  57. }
  58. };
  59. viewPager.setAdapter(pagerAdapter);
  60. }
  61. }

PagerTitleStrip的效果

viewpager_02

PagerTabStrip的效果

viewpager_03

循环滑动

前面的ViewPager当滑动到第一个的时候,再想往左滑就滑不动了;当滑动到最后一个的时候,再想往右滑也滑不懂了。如果想实现上述效果,需要重写PagerAdapter的几个方法。

  1. PagerAdapter pagerAdapter = new PagerAdapter() {
  2. @Override
  3. public int getCount() {
  4. return Integer.MAX_VALUE;
  5. }
  6. @Override
  7. public boolean isViewFromObject(View view, Object object) {
  8. return view == object;
  9. }
  10. @Override
  11. public void destroyItem(ViewGroup container, int position, Object object) {
  12. // super.destroyItem(container, position, object);
  13. container.removeView(views.get(position % views.size()));
  14. }
  15. @Override
  16. public Object instantiateItem(ViewGroup container, int position) {
  17. // return super.instantiateItem(container, position);
  18. container.addView(views.get(position % views.size()));
  19. return views.get(position % views.size());
  20. }
  21. @Override
  22. public CharSequence getPageTitle(int position) {
  23. // return super.getPageTitle(position);
  24. return titleList.get(position % views.size());
  25. }
  26. };

viewpager_04

本文源码下载

转载请注明作者和出处,并添加本页链接。
原文链接: https://xugaoxiang.com/75

给我留言