Android學習筆記32:滑屏控件ViewPager的使用


  在Android開發中,使用ViewPager控件可以輕松實現多個頁面的滑動顯示效果。需要注意的一點是,在Android3.0版本的SDK之后提供了android-support-v4.jar包,用於實現版本的兼容,讓老版本系統下的應用通過加載這個包實現擴展。所以在使用ViewPager控件時,可以根據需要往工程中導入android-support-v4.jar包。

  在本篇博文中,我將以一個簡單的例子演示如何使用ViewPager控件實現滑屏顯示效果。完成后的運行效果如圖1所示。

圖1 ViewPager效果圖

  (說明:圖1中所示新聞圖片來自鳳凰網和騰訊網,特此說明。)

  在該實例中,我制作了一個類似新聞導航功能的UI界面,頂端有四個選項卡“首頁”、“新聞”、“娛樂”以及“博客”,每個選項卡的下面會顯示與之相應的選項內容(該實例主要是為了學習ViewPager控件的使用,所以目前只實現了“新聞”選項卡下面的內容)。在“新聞”選項內,使用ViewPager控件實現了三條新聞的滑動顯示效果,通過左右拖動頁面可以進行頁面的切換,同時,在頁面的下方還實現了一個頁面指示器,可以告訴用戶總共可以滑動幾屏,以及當前頁面所處的位置是第幾屏。

  下面就來詳細說說這個實例的具體實現過程。

 

1.主界面設計

  由圖1可以看出,該實例的主界面是由四部分組成的:頂端的導航條、新聞圖片、新聞正文概要、底端的頁面指示器。

  主界面布局使用FrameLayout作為主布局格式,目的在於當ViewPager控件左右滑動顯示不同的新聞內容時,頂端的導航條和底端的頁面指示器不受影響,而顯示在最上層。

  具體的主界面布局源代碼如下:

 1   <FrameLayout 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       <!-- 頂端導航欄 -->
 7       <include 
 8           layout="@layout/layout_include"/>
 9       
10       <!-- 滑屏界面 -->
11       <android.support.v4.view.ViewPager
12           android:id="@+id/viewpager"
13           android:layout_width="wrap_content"
14           android:layout_height="wrap_content"
15           android:layout_marginTop="34dp"
16           android:layout_gravity="center"    >
17           <!-- 
18           <android.support.v4.view.PagerTitleStrip
19               android:id="@+id/viewpagetitle"
20               android:layout_width="wrap_content"
21               android:layout_height="wrap_content"
22               android:layout_gravity="top"    >
23           </android.support.v4.view.PagerTitleStrip>
24           -->
25       </android.support.v4.view.ViewPager>
26       
27       <!-- 底端的頁面指示器 -->
28       <RelativeLayout 
29           android:layout_width="match_parent"
30           android:layout_height="wrap_content"    >
31           <LinearLayout 
32               android:id="@+id/page_indicator"
33               android:layout_width="match_parent"
34               android:layout_height="wrap_content"
35               android:orientation="horizontal"
36               android:gravity="center_horizontal"
37               android:layout_marginTop="400dp"    >
38               </LinearLayout>
39       </RelativeLayout>
40   </FrameLayout>

  其中,主界面中有關導航欄的控件布局定義在了xml文件layout_include.xml中,然后,通過使用了<include></include>標簽將導航欄的布局文件靜態的加載到了主界面布局中來,使主界面的布局文件結構更加清晰,同時也便於代碼維護。

  有關靜態布局文件的加載可以參看《Android學習筆記31:使用惰性控件ViewStub實現布局動態加載》(http://www.cnblogs.com/menlsh/archive/2013/03/17/2965217.html)。

  有一點需要注意,ViewPager控件的xml標簽和普通的Android控件標簽不太一樣,需要使用<android.support.v4.view.ViewPager></android.support.v4.view.ViewPager>的形式,將包名也包含其中。並且,ViewPager控件還提供了一個內嵌的滑屏標題控件<android.support.v4.view.PagerTitleStrip></android.support.v4.view.PagerTitleStrip>,可以用於設置每一屏的標題。在該實例中,並未使用該控件,所以將其注釋掉了。

  此外,在主界面布局文件的最后,定義了一個水平的線性布局LinearLayout,用來動態的加載頁面指示器。

  至此,該實例的主界面就設計好了。

 

2.ViewPager界面設計

  在該實例中,有3張不同的ViewPager界面,每張ViewPager界面都是有兩部分構成的:新聞圖片和新聞正文概要。當然了,每張ViewPager界面顯示的內容都是不同的,所以需要分別進行布局設計。

  在本實例中,每張ViewPager界面布局的格式都是一樣的,使用垂直線性布局LinearLayout將ViewPager界面划分為兩部分,上部分使用ImageView控件顯示新聞圖片,下部分使用TextView顯示新聞正文概要。

  該實例中的第一條新聞報道的ViewPager界面布局源代碼如下:

 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="wrap_content"
 5       android:orientation="vertical" >
 6       
 7       <ImageView 
 8           android:layout_width="match_parent"
 9           android:layout_height="wrap_content"
10           android:scaleType="center"
11           android:src="@drawable/visitor"    />
12       <TextView 
13           android:layout_width="match_parent"
14           android:layout_height="wrap_content"
15           android:layout_marginTop="5dp"
16           android:layout_marginLeft="20dp"
17           android:layout_marginRight="20dp"
18           android:text="@string/news_content_one"    />
19   
20   </LinearLayout>

  其它兩張ViewPager界面的布局文件和如上的代碼大同小異,這里就不再贅述了。我將這3張ViewPager界面的布局文件分別命名為了“layout_news_one”、“layout_news_two”、“layout_news_three”,在PagerAdapter中需要加載這3個xml文件。

 

3.頁面適配器PagerAdapter

  如何加載每一屏的內容到ViewPager控件中呢?答案是使用頁面適配器PagerAdapter。

  PagerAdapter是一個抽象類,在繼承PagerAdapter類時,必須要實現PagerAdapter類的四個抽象方法:

  (1)public Object instantiateItem (ViewGroup container, int position);

  (2)public void destroyItem (ViewGroup container, int position, Object object);

  (3)public abstract int getCount ();

  (4)public abstract boolean isViewFromObject (View view, Object object);

  其中,instantiateItem()方法的作用是初始化ViewPager中的項;destroyItem()方法的作用是銷毀ViewPager中的項;getCount()方法的作用是獲取ViewPager中有多少項(有幾屏);isViewFromObject()方法的作用是判斷是否由對象生成界面。

  在該實例中,新建了一個繼承自PagerAdapter的MyPagerAdapter類,並實現了以上的抽象方法。該類的具體實現如下:

 1   package com.example.android_viewpager;
 2   
 3   import java.util.ArrayList;
 4   import java.util.List;
 5   
 6   import android.content.Context;
 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   
12   public class MyPagerAdapter extends PagerAdapter {
13   
14       List<View> mListViewPager;            //ViewPager對象的內容
15       List<String> mListViewPagerTitle;        //ViewPager對象的標題(未使用)
16       Context mContext;
17       
18       public MyPagerAdapter(Context Context) {
19           this.mContext = Context;
20           
21           //加載xml文件到ViewPager對象中
22           View viewPagerNews1 = LayoutInflater.from(mContext).inflate(R.layout.layout_news_one, null);
23           View viewPagerNews2 = LayoutInflater.from(mContext).inflate(R.layout.layout_news_two, null);
24           View viewPagerNews3 = LayoutInflater.from(mContext).inflate(R.layout.layout_news_three, null);
25           mListViewPager = new ArrayList<View>();
26           mListViewPager.add(viewPagerNews1);
27           mListViewPager.add(viewPagerNews2);
28           mListViewPager.add(viewPagerNews3);
29       }
30       
31       //獲取ViewPager的頁數
32       public int getCount() {
33           return mListViewPager.size();
34       }
35       
36       //初始化ViewPager中的項
37       public Object instantiateItem(View container, int position) {
38           ((ViewPager)container).addView(mListViewPager.get(position));
39           return mListViewPager.get(position);
40       }
41       
42       //獲取每個ViewPager的標題
43       public CharSequence getPageTitle(int position) {
44           return mListViewPagerTitle.get(position);
45       }
46   
47       //判斷是否由對象生成界面
48       public boolean isViewFromObject(View view, Object object) {
49           return view == object;
50       }
51   
52       //銷毀ViewPager中的項
53       public void destroyItem(View container, int position, Object object) {
54           ((ViewPager)container).removeView(mListViewPager.get(position));
55       }
56   }

  此外,還需要使用ViewPager類的setAdapter (PagerAdapter adapter)方法加載該自定義的MyPagerAdapter適配器。

 

4.ViewPager事件監聽

  在該實例中,我們需要對ViewPager進行事件監聽,以便實現底端的頁面指示器功能。

  要實現ViewPager的事件監聽,我們可以根據需要實現OnPageChangeListener接口中的以下3個事件監聽處理方法:

  (1)public abstract void onPageScrollStateChanged (int state);

  (2)public abstract void onPageScrolled (int position, float positionOffset, int positionOffsetPixels);

  (3)public abstract void onPageSelected (int position);

  這3個方法的調用時機各不一樣。其中,onPageScrollStateChanged()方法發生在滾動狀態變化時,用於監測用戶開始拖動ViewPager;onPageScrolled()方法發生在當前頁面滾動時,用於監測用於拖動當前頁面的程度(偏移量多少);onPageSelected()方法發生在當前頁面被選擇時,用於監測當前滑動到了哪一個頁面。

  顯然,要實現底端的頁面指示器功能,我們需要實現onPageSelected()方法。實現方法如下:

 1   /*
 2      * Function  :    事件監聽處理
 3      * Author    :    博客園-依舊淡然
 4      */
 5     public void onPageSelected(int position) {
 6         for(int i = 0; i < myPagerAdapter.getCount(); i++)    {
 7             if(position == i) {
 8                 mIndicatorList[position].setBackgroundResource(R.drawable.page_indicator_big);
 9             }    else {
10                 mIndicatorList[i].setBackgroundResource(R.drawable.page_indicator_small);
11             }
12         }
13     }

  通過以上的方法,我們便實現了底端的頁面指示器功能,讓當前的顯示頁面在指示器中以大圓圈表示。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM