Android App开发中ViewPager组件的入门使用教程

作者:harvic880925 时间:2023-04-30 21:45:34 

首先让大家有个全局的认识,直接上个项目,看看仅仅通过这几行代码,竟然就能完成如此强悍的功能。下篇再仔细讲讲为什么要这么写。
效果图:
实现了三个view间的相互滑动
第一个VIEW向第二个VIEW滑动:

Android App开发中ViewPager组件的入门使用教程

第二个VIEW向第三个VIEW滑动:

Android App开发中ViewPager组件的入门使用教程

一、新建项目,引入ViewPager控件
ViewPager。它是google SDk中自带的一个附加包的一个类,可以用来实现屏幕间的切换。

1.在主布局文件里加入


<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:tools="http://schemas.android.com/tools"
 android:layout_width="fill_parent"
 android:layout_height="fill_parent"
 tools:context="com.example.testviewpage_1.MainActivity" >

<android.support.v4.view.ViewPager
 android:id="@+id/viewpager"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_gravity="center" />

</RelativeLayout>

其中 <android.support.v4.view.ViewPager /> 是ViewPager对应的组件,要将其放到想要滑动的位置

2、新建三个layout,用于滑动切换的视图
从效果图中也可以看到,我们的三个视图都非常简单,里面没有任何的控件,大家当然可以往里添加各种控件,但这里是个DEMO,只详解原理即可,所以我这里仅仅用背景来区别不用layout布局。

布局代码分别如下:

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:background="#ffffff"
 android:orientation="vertical" >

</LinearLayout>

layout2.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:background="#ffff00"
 android:orientation="vertical" >

</LinearLayout>

layout3.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:background="#ff00ff"
 android:orientation="vertical" >

</LinearLayout><span style="color:#660000;">
</span>

二、代码实战
先上整体代码,然后逐步讲解。


package com.example.testviewpage_1;

import java.util.ArrayList;
import java.util.List;
import java.util.zip.Inflater;

import android.app.Activity;
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.view.ViewGroup;

public class MainActivity extends Activity {

private View view1, view2, view3;
 private ViewPager viewPager; //对应的viewPager

private List<View> viewList;//view数组

@Override
 protected void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   setContentView(R.layout.activity_main);

viewPager = (ViewPager) findViewById(R.id.viewpager);
   LayoutInflater inflater=getLayoutInflater();
   view1 = inflater.inflate(R.layout.layout1, null);
   view2 = inflater.inflate(R.layout.layout2,null);
   view3 = inflater.inflate(R.layout.layout3, null);

viewList = new ArrayList<View>();// 将要分页显示的View装入数组中
   viewList.add(view1);
   viewList.add(view2);
   viewList.add(view3);

PagerAdapter pagerAdapter = new PagerAdapter() {

@Override
     public boolean isViewFromObject(View arg0, Object arg1) {
       // TODO Auto-generated method stub
       return arg0 == arg1;
     }

@Override
     public int getCount() {
       // TODO Auto-generated method stub
       return viewList.size();
     }

@Override
     public void destroyItem(ViewGroup container, int position,
         Object object) {
       // TODO Auto-generated method stub
       container.removeView(viewList.get(position));
     }

@Override
     public Object instantiateItem(ViewGroup container, int position) {
       // TODO Auto-generated method stub
       container.addView(viewList.get(position));

return viewList.get(position);
     }
   };

viewPager.setAdapter(pagerAdapter);

}

}

代码量很小,全部放在了OnCreate()函数中。
1、先看声明的变量的意义:


private View view1, view2, view3;
private List<View> viewList;//view数组
private ViewPager viewPager; //对应的viewPager

首先viewPager对应 <android.support.v4.view.ViewPager/>控件。

view1,view2 ,view3对应我们的三个layout,即layout1.xml,layout2.xml,layout3.xml
viewList是一个View数组,盛装上面的三个VIEW

2、接下来是他们的初始化过程:


viewPager = (ViewPager) findViewById(R.id.viewpager);
LayoutInflater inflater=getLayoutInflater();
view1 = inflater.inflate(R.layout.layout1, null);
view2 = inflater.inflate(R.layout.layout2,null);
view3 = inflater.inflate(R.layout.layout3, null);

viewList = new ArrayList<View>();// 将要分页显示的View装入数组中
viewList.add(view1);
viewList.add(view2);
viewList.add(view3);

初始化过程难度不大,就是将资源与变量联系起来布局,最后将实例化的view1,view2,view3添加到viewList中
3、PageAdapter——PageView的适配器
适配器这个东东想必大家都不莫生,在ListView中也有适配器,listView通过重写GetView()函数来获取当前要加载的Item。而PageAdapter不太相同,毕竟PageAdapter是单个VIew的合集。

PageAdapter 必须重写的四个函数:

(1)boolean isViewFromObject(View arg0, Object arg1)
(2)int getCount()
(3)void destroyItem(ViewGroup container, int position,Object object)
(4)Object instantiateItem(ViewGroup container, int position)
先看看各个函数,我们上面都做了什么吧:


@Override
public int getCount() {
 // TODO Auto-generated method stub
 return viewList.size();
}

getCount():返回要滑动的VIew的个数


@Override
public void destroyItem(ViewGroup container, int position,
   Object object) {
 // TODO Auto-generated method stub
 container.removeView(viewList.get(position));
}

destroyItem():从当前container中删除指定位置(position)的View;


@Override
public Object instantiateItem(ViewGroup container, int position) {
 // TODO Auto-generated method stub
   container.addView(viewList.get(position));

return viewList.get(position);
 }
};

instantiateItem():做了两件事,第一:将当前视图添加到container中,第二:返回当前View


@Override
public boolean isViewFromObject(View arg0, Object arg1) {
 // TODO Auto-generated method stub
 return arg0 == arg1;
}

isViewFromObject():对于这个函数就先不做讲解,大家目前先知道它要这样重写就行了,后面我们会对它进行改写。 

三、对键Key的理解
viewpager不直接处理每一个视图而是将各个视图与一个键联系起来。这个键用来跟踪且唯一代表一个页面,不仅如此,该键还独立于这个页面所在adapter的位置。当pageradapter将要改变的时候他会调用startUpdate函数,接下来会调用一次或多次的instantiateItem或者destroyItem。最后在更新的后期会调用finishUpdate。当finishUpdate返回时 instantiateItem返回的对象应该添加到父ViewGroup destroyItem返回的对象应该被ViewGroup删除。methodisViewFromObject(View, Object)代表了当前的页面是否与给定的键相关联。

对于非常简单的pageradapter或许你可以选择用page本身作为键,在创建并且添加到viewgroup后instantiateItem方法里返回该page本身即可destroyItem将会将该page从viewgroup里面移除。isViewFromObject方法里面直接可以返回view == object。
经过上面的讲解和实战例子,想必大家给Key的概念应该有个清楚的理解,下面举个例子来说明Key与View的关系,由于Key与View要一一对应,所以我把每个视图所处的位置Position作为Key,在上章例子的基础上更改的,下面先看全部代码,然后看部分讲解:


package com.example.testviewpage_2;
/**
* @author harvic
* @date 2014.8.11
*/
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
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.view.ViewGroup;

public class MainActivity extends Activity {

private View view1, view2, view3;
 private List<View> viewList;// view数组
 private ViewPager viewPager; // 对应的viewPager

@Override
 protected void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   setContentView(R.layout.activity_main);
   viewPager = (ViewPager) findViewById(R.id.viewpager);
   LayoutInflater inflater = getLayoutInflater();
   view1 = inflater.inflate(R.layout.layout1, null);
   view2 = inflater.inflate(R.layout.layout2, null);
   view3 = inflater.inflate(R.layout.layout3, null);

viewList = new ArrayList<View>();// 将要分页显示的View装入数组中
   viewList.add(view1);
   viewList.add(view2);
   viewList.add(view3);

PagerAdapter pagerAdapter = new PagerAdapter() {

@Override
     public boolean isViewFromObject(View arg0, Object arg1) {
       // TODO Auto-generated method stub
       //根据传来的key,找到view,判断与传来的参数View arg0是不是同一个视图
       return arg0 == viewList.get((int)Integer.parseInt(arg1.toString()));
     }

@Override
     public int getCount() {
       // TODO Auto-generated method stub
       return viewList.size();
     }

@Override
     public void destroyItem(ViewGroup container, int position,
         Object object) {
       // TODO Auto-generated method stub
       container.removeView(viewList.get(position));
     }

@Override
     public Object instantiateItem(ViewGroup container, int position) {
       // TODO Auto-generated method stub
       container.addView(viewList.get(position));

//把当前新增视图的位置(position)作为Key传过去
       return position;
     }
   };

viewPager.setAdapter(pagerAdapter);

}

}

在这里更改了两个地方:
1、先看Key的产生的位置instantiateItem()


@Override
public Object instantiateItem(ViewGroup container, int position) {
 // TODO Auto-generated method stub
 container.addView(viewList.get(position));

//把当前新增视图的位置(position)作为Key传过去
 return position;
}

在这个函数中Key是作为返回值与当前装入Container中的视图对应起来的。所以在这里我们返回postion与container.addView(viewList.get(position));里的viewList.get(position)这个视图对应起来。
2、isViewFromObject ()


@Override
public boolean isViewFromObject(View arg0, Object arg1) {
 // TODO Auto-generated method stub
 //根据传来的key,找到view,判断与传来的参数View arg0是不是同一个视图
 return arg0 == viewList.get((int)Integer.parseInt(arg1.toString()));
}

判断从instantiateItem()返回来的Key与当前的View是否能对应起来,我们知道从instantiateItem传过来的其实是position,所以我们要根据position找到View,然后跟参数中的View arg0判断。

但在真正操作时出现了问题,我们要先将obect对应转换为int类型:(int)Integer.parseInt(arg1.toString());然后再根据position找到对应的View;

效果图:三个View之间的滑动切换

Android App开发中ViewPager组件的入门使用教程Android App开发中ViewPager组件的入门使用教程       

标签:Android,ViewPager
0
投稿

猜你喜欢

  • 深入理解Java显式锁的相关知识

    2022-06-16 09:59:41
  • C#中使用强制类型实现字符串和ASCII码之间的转换

    2022-05-15 14:57:48
  • LRU缓存替换策略及C#实现方法分享

    2021-08-27 04:20:49
  • android实现简单的活动转盘

    2022-11-29 08:40:35
  • Java实现图形界面计算器

    2023-06-05 11:53:23
  • Java中的回调

    2023-11-16 01:55:58
  • Android游戏开发之黑白棋

    2023-05-24 13:39:03
  • C# TabControl控件中TabPage选项卡切换时的触发事件问题

    2022-10-30 08:11:13
  • FloatingActionButton增强版一个按钮跳出多个按钮第三方开源之FloatingActionButton

    2023-06-18 13:28:22
  • C# 关于AppDomain的一些总结

    2022-07-18 09:30:18
  • 微信小程序支付C#后端源码

    2023-11-21 15:06:29
  • Go返回int64类型字段超出javascript Number范围的解决方法

    2023-08-27 05:15:01
  • Android自定义View实现钟摆效果进度条PendulumView

    2022-07-04 15:50:14
  • C#子类对基类方法的继承、重写与隐藏详解

    2023-01-31 04:48:46
  • java并发编程工具类JUC之ArrayBlockingQueue

    2023-07-04 21:02:20
  • spring cloud oauth2 feign 遇到的坑及解决

    2022-06-15 13:06:06
  • Android实现移动小球和CircularReveal页面切换动画实例代码

    2023-03-03 03:45:50
  • Android Studio进行APP图标更改的两种方式总结

    2022-02-07 09:08:40
  • SpringBoot获取配置文件内容的几种方式总结

    2023-11-24 18:10:48
  • java实现学生成绩档案管理系统

    2023-06-29 22:48:43
  • asp之家 软件编程 m.aspxhome.com