Android App開發(fā)中ViewPager組件的入門使用教程
首先讓大家有個全局的認識,直接上個項目,看看僅僅通過這幾行代碼,竟然就能完成如此強悍的功能。下篇再仔細講講為什么要這么寫。
效果圖:
實現(xiàn)了三個view間的相互滑動
第一個VIEW向第二個VIEW滑動:

第二個VIEW向第三個VIEW滑動:

一、新建項目,引入ViewPager控件
ViewPager。它是google SDk中自帶的一個附加包的一個類,可以用來實現(xiàn)屏幕間的切換。
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,只詳解原理即可,所以我這里僅僅用背景來區(qū)別不用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>
二、代碼實戰(zhàn)
先上整體代碼,然后逐步講解。
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數(shù)組
@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裝入數(shù)組中
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()函數(shù)中。
1、先看聲明的變量的意義:
private View view1, view2, view3; private List<View> viewList;//view數(shù)組 private ViewPager viewPager; //對應的viewPager
首先viewPager對應 <android.support.v4.view.ViewPager/>控件。
view1,view2 ,view3對應我們的三個layout,即layout1.xml,layout2.xml,layout3.xml
viewList是一個View數(shù)組,盛裝上面的三個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裝入數(shù)組中 viewList.add(view1); viewList.add(view2); viewList.add(view3);
初始化過程難度不大,就是將資源與變量聯(lián)系起來布局,最后將實例化的view1,view2,view3添加到viewList中
3、PageAdapter——PageView的適配器
適配器這個東東想必大家都不莫生,在ListView中也有適配器,listView通過重寫GetView()函數(shù)來獲取當前要加載的Item。而PageAdapter不太相同,畢竟PageAdapter是單個VIew的合集。
PageAdapter 必須重寫的四個函數(shù):
(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)
先看看各個函數(shù),我們上面都做了什么吧:
@Override
public int getCount() {
// TODO Auto-generated method stub
return viewList.size();
}
getCount():返回要滑動的VIew的個數(shù)
@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():對于這個函數(shù)就先不做講解,大家目前先知道它要這樣重寫就行了,后面我們會對它進行改寫。
三、對鍵Key的理解
viewpager不直接處理每一個視圖而是將各個視圖與一個鍵聯(lián)系起來。這個鍵用來跟蹤且唯一代表一個頁面,不僅如此,該鍵還獨立于這個頁面所在adapter的位置。當pageradapter將要改變的時候他會調用startUpdate函數(shù),接下來會調用一次或多次的instantiateItem或者destroyItem。最后在更新的后期會調用finishUpdate。當finishUpdate返回時 instantiateItem返回的對象應該添加到父ViewGroup destroyItem返回的對象應該被ViewGroup刪除。methodisViewFromObject(View, Object)代表了當前的頁面是否與給定的鍵相關聯(lián)。
對于非常簡單的pageradapter或許你可以選擇用page本身作為鍵,在創(chuàng)建并且添加到viewgroup后instantiateItem方法里返回該page本身即可destroyItem將會將該page從viewgroup里面移除。isViewFromObject方法里面直接可以返回view == object。
經(jīng)過上面的講解和實戰(zhàn)例子,想必大家給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數(shù)組
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裝入數(shù)組中
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
//根據(jù)傳來的key,找到view,判斷與傳來的參數(shù)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的產(chǎn)生的位置instantiateItem()
@Override
public Object instantiateItem(ViewGroup container, int position) {
// TODO Auto-generated method stub
container.addView(viewList.get(position));
//把當前新增視圖的位置(position)作為Key傳過去
return position;
}
在這個函數(shù)中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
//根據(jù)傳來的key,找到view,判斷與傳來的參數(shù)View arg0是不是同一個視圖
return arg0 == viewList.get((int)Integer.parseInt(arg1.toString()));
}
判斷從instantiateItem()返回來的Key與當前的View是否能對應起來,我們知道從instantiateItem傳過來的其實是position,所以我們要根據(jù)position找到View,然后跟參數(shù)中的View arg0判斷。
但在真正操作時出現(xiàn)了問題,我們要先將obect對應轉換為int類型:(int)Integer.parseInt(arg1.toString());然后再根據(jù)position找到對應的View;
效果圖:三個View之間的滑動切換

- Android中ViewPager的PagerTabStrip與PagerTitleStrip用法實例
- Android中的ViewPager視圖滑動切換類的入門實例教程
- Android實現(xiàn)千變?nèi)f化的ViewPager切換動畫
- Android自定義ViewPager實現(xiàn)個性化的圖片切換效果
- Android利用HorizontalScrollView仿ViewPager設計簡單相冊
- Android ViewPager制作新手導航頁(動態(tài)加載)
- Android App中用Handler實現(xiàn)ViewPager頁面的自動切換
- 實例講解Android中ViewPager組件的一些進階使用技巧
- 舉例講解Android中ViewPager中的PagerTitleStrip子控件
- Android應用中利用ViewPager實現(xiàn)多頁面滑動切換效果示例
- 詳解Android App中創(chuàng)建ViewPager組件的方法
- Android中viewPager使用指南
- Android中ViewPager實現(xiàn)滑動條及與Fragment結合的實例教程
相關文章
圖解 Kotlin SharedFlow 緩存系統(tǒng)及示例詳解
這篇文章主要為大家介紹了圖解 Kotlin SharedFlow 緩存系統(tǒng)及示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-10-10
Android?獲取實時網(wǎng)速實現(xiàn)詳解
這篇文章主要為大家介紹了Android?獲取實時網(wǎng)速實現(xiàn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-11-11
Android編程中出現(xiàn)The connection to adb is down問題的解決方法
這篇文章主要介紹了Android編程中出現(xiàn)The connection to adb is down問題的解決方法,涉及Android進程與服務的相關操作技巧,需要的朋友可以參考下2015-12-12
Android基礎入門之dataBinding的簡單使用教程
DataBinding 是谷歌官方發(fā)布的一個框架,顧名思義即為數(shù)據(jù)綁定,下面這篇文章主要給大家介紹了關于Android基礎入門之dataBinding的簡單使用,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下2022-06-06
使用Android studio3.6的java api方式調用opencv
這篇文章主要介紹了Android studio3.6的java api方式調用opencv的代碼詳解,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-03-03

