共用方式為


使用檢視的 ViewPager

ViewPager 是一個版面配置管理員,可讓您實作 Gestural 流覽。 Gestural 瀏覽可讓使用者向左撥動和向右撥動,以逐步瀏覽數據頁面。 本指南說明如何使用 ViewPager 和 PagerTabStrip 實作可撥動 UI,使用 Views 作為數據頁(後續指南將說明如何使用分頁片段)。

概觀

本指南是逐步解說,提供逐步示範如何使用 來 ViewPager 實作落葉和常綠樹的映像庫。 在此應用程式中,使用者透過「樹狀目錄」向左和向右撥動,以檢視樹狀結構影像。 在目錄的每個頁面頂端,樹狀結構的名稱會列在 中PagerTabStrip,而樹狀結構的影像會顯示在 中 ImageView。 配接器可用來將 介面 ViewPager 連接到基礎數據模型。 此應用程式會實作衍生自 PagerAdapter的配接器。

雖然 ViewPager以 為基礎的應用程式通常會使用 Fragment來實作,但有一些相對簡單的使用案例,其中不需要 額外的複雜度 Fragment。 例如,本逐步解說中說明的基本映像庫應用程式不需要使用 Fragment。 由於內容是靜態的,而且使用者只會在不同影像之間來回撥動,因此實作可以使用標準 Android 檢視和版面配置來保持更簡單。

啟動應用程式專案

建立名為 TreePager 的新 Android 專案(如需建立新 Android 專案的詳細資訊,請參閱 Hello,Android )。 接下來,啟動 NuGet 封裝管理員。 (如需安裝 NuGet 套件的詳細資訊,請參閱 逐步解說:在您的專案中加入 NuGet。 尋找並安裝 Android 支援連結庫 v4

NuGet 封裝管理員 中選取的支援 v4 NuGet 螢幕快照

這也會安裝 Android 支援連結庫 v4 所要求的任何其他套件。

新增範例數據源

在此範例中,樹狀目錄數據源(由 TreeCatalog 類別表示)會 ViewPager 提供項目內容。 TreeCatalog 包含樹狀結構影像和樹狀結構標題的現成集合,配接器將用於建立 View。 建 TreeCatalog 構函式不需要自變數:

TreeCatalog treeCatalog = new TreeCatalog();

中的 TreeCatalog 影像集合會組織,讓索引器可以存取每個影像。 例如,下列程式代碼行會擷取集合中第三個映像的映像資源識別碼:

int imageId = treeCatalog[2].imageId;

由於的 TreeCatalog 實作詳細數據與了解 ViewPager無關,因此此處並未列出程序 TreeCatalog 代碼。 的原始程式碼TreeCatalog可在 TreeCatalog.cs 取得。 下載此原始程式檔(或將程式代碼複製並貼到新的 TreeCatalog.cs 檔案中),並將其新增至您的專案。 此外,請將圖像文件下載並解壓縮到您的 Resources/drawable 資料夾,並將其包含在專案中。

建立 ViewPager 版面配置

開啟 Resources/layout/Main.axml ,並將其內容取代為下列 XML:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.view.ViewPager
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/viewpager"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

</android.support.v4.view.ViewPager>

此 XML 定義 ViewPager 佔用整個畫面的 。 請注意,您必須使用完整名稱 android.support.v4.view.ViewPager ,因為 ViewPager 已封裝在支持連結庫中。 ViewPager 僅適用於 Android 支援連結庫 v4;無法在 Android SDK 中使用。

設定 ViewPager

編輯 MainActivity.cs 並新增下列 using 語句:

using Android.Support.V4.View;

以下列程式碼取代 OnCreate 方法:

protected override void OnCreate(Bundle bundle)
{
    base.OnCreate(bundle);
    SetContentView(Resource.Layout.Main);
    ViewPager viewPager = FindViewById<ViewPager>(Resource.Id.viewpager);
    TreeCatalog treeCatalog = new TreeCatalog();
}

此程式碼會執行下列操作:

  1. Main.axml 配置資源設定檢視。

  2. 從版面配置擷取 的參考 ViewPager

  3. 將新的 TreeCatalog 具現化為數據源。

當您建置並執行此程式代碼時,您應該會看到類似下列螢幕快照的顯示:

顯示空白 ViewPager 的應用程式螢幕快照

此時,是空的ViewPager,因為它缺少用來存取 TreeCatalog內容的配接器。 在下一 節中,會建立 PagerAdapter 以連線 ViewPagerTreeCatalog

建立配接器

ViewPager會使用位於 和數據源之間的ViewPager配接器控制器物件(請參閱配接器中的圖例)。 若要存取此數據, ViewPager 您必須提供衍生自 PagerAdapter的自定義配接器。 此配接器會以數據源的內容填入每個 ViewPager 頁面。 由於此數據來源是應用程式特定的,因此自定義配接器是瞭解如何存取資料的程序代碼。 當使用者撥動 頁面 ViewPager時,配接器會從數據源擷取資訊,並將其載入頁面以供 ViewPager 顯示。

當您實作 PagerAdapter時,必須覆寫下列專案:

  • InstantiateItem – 建立指定位置的頁面 (View),並將其新增至 ViewPager檢視的集合。

  • DestroyItem – 從指定位置移除頁面。

  • Count – 只讀屬性,可傳回可用的檢視數 (pages) 數目。

  • IsViewFromObject – 判斷頁面是否與特定索引鍵對象相關聯。 (這個物件是由 InstantiateItem 方法所建立。在此範例中,索引鍵對像是 TreeCatalog 數據物件。

新增名為 TreePagerAdapter.cs 的新檔案,並以下列程式代碼取代其內容:

using System;
using Android.App;
using Android.Runtime;
using Android.Content;
using Android.Views;
using Android.Widget;
using Android.Support.V4.View;
using Java.Lang;

namespace TreePager
{
    class TreePagerAdapter : PagerAdapter
    {
        public override int Count
        {
            get { throw new NotImplementedException(); }
        }

        public override bool IsViewFromObject(View view, Java.Lang.Object obj)
        {
            throw new NotImplementedException();
        }

        public override Java.Lang.Object InstantiateItem (View container, int position)
        {
            throw new NotImplementedException();
        }

        public override void DestroyItem(View container, int position, Java.Lang.Object view)
        {
            throw new NotImplementedException();
        }
    }
}

此程式代碼會存根基本 PagerAdapter 實作。 在下列各節中,這些方法都會取代為使用中的程序代碼。

實作建構函式

當應用程式具現化 TreePagerAdapter時,它會提供內容 ( MainActivity、 和 具現化 TreeCatalog的 。 將下列成員變數和建構函式新增至 類別頂TreePagerAdapter端TreePagerAdapter.cs

Context context;
TreeCatalog treeCatalog;

public TreePagerAdapter (Context context, TreeCatalog treeCatalog)
{
    this.context = context;
    this.treeCatalog = treeCatalog;
}

此建構函式的目的是儲存 將使用的內容和 TreeCatalog 實例 TreePagerAdapter

實作計數

實作 Count 相當簡單:它會傳回樹目錄中的樹狀結構數目。 以下列程式碼取代 Count

public override int Count
{
    get { return treeCatalog.NumTrees; }
}

NumTrees TreeCatalog 屬性會傳回數據集中的樹狀結構數目(頁數)。

實作 InstantiateItem

方法 InstantiateItem 會建立指定位置的頁面。 它也必須將新建立的檢視加入至 ViewPager的檢視集合。 若要使這個可行,會將 ViewPager 本身當做容器參數傳遞。

以下列程式碼取代 InstantiateItem 方法:

public override Java.Lang.Object InstantiateItem (View container, int position)
{
    var imageView = new ImageView (context);
    imageView.SetImageResource (treeCatalog[position].imageId);
    var viewPager = container.JavaCast<ViewPager>();
    viewPager.AddView (imageView);
    return imageView;
}

此程式碼會執行下列操作:

  1. 具現化新的 ImageView ,以顯示位於指定位置的樹狀結構影像。 應用程式的 MainActivity 是將傳遞至 ImageView 建構函式的內容。

  2. ImageView 資源設定為 TreeCatalog 位於指定位置的影像資源標識碼。

  3. 將傳遞的容器ViewViewPager轉換為參考。 請注意,您必須使用 JavaCast<ViewPager>() 來正確執行此轉換(這是必要的,讓 Android 執行運行時間檢查的類型轉換)。

  4. 將 具現化 ImageView 的 加入至 ViewPager ,並將 傳回 ImageView 給呼叫端。

顯示位於ViewPagerposition影像時,會顯示這個 ImageView。 一開始,會呼叫兩次, InstantiateItem 以填入前兩個頁面的檢視。 當使用者捲動時,會再次呼叫來維護目前顯示專案後面的檢視。

實作 DestroyItem

方法 DestroyItem 會從指定位置移除頁面。 在任何指定位置的檢視可以變更的應用程式中, ViewPager 必須先有某種方式移除該位置的過時檢視,才能將檢視取代為新的檢視。 在此範例中TreeCatalog,每個位置的檢視不會變更,因此在針對該位置呼叫 時InstantiateItem,只會重新新增 所DestroyItem移除的檢視。 (為了提高效率,可以實作集區來回收 View會以相同位置重新顯示。

以下列程式碼取代 DestroyItem 方法:

public override void DestroyItem(View container, int position, Java.Lang.Object view)
{
    var viewPager = container.JavaCast<ViewPager>();
    viewPager.RemoveView(view as View);
}

此程式碼會執行下列操作:

  1. 將傳遞的容器 View 轉換成 ViewPager 參考。

  2. 將傳遞的 Java 物件 (view) 轉換成 C# Viewview as View):

  3. ViewPager移除檢視。

實作 IsViewFromObject

當使用者向左和向右滑過內容頁面時, ViewPager 呼叫 IsViewFromObject 來確認位於指定位置的子系 View 與該相同位置的配接器對象相關聯(因此,配接器的對象稱為 物件索引鍵)。 對於相對簡單的應用程式而言,關聯是其中一個身分識別 – 該實例上的配接器物件索引鍵是先前透過 傳回至 ViewPager InstantiateItem的檢視。 不過,對於其他應用程式,物件索引鍵可能是與在該位置上顯示之子檢視相關聯的一些其他配接器特定類別實例。但與該位置上顯示的物件索引 ViewPager 鍵不同。 只有配接器知道傳遞的檢視和物件索引鍵是否相關聯。

IsViewFromObject 必須實作 , PagerAdapter 才能正常運作。 如果 IsViewFromObject 針對指定位置傳 false 回 , ViewPager 則不會在該位置顯示檢視。 在TreePager應用程式中,傳InstantiateItem回的物件索引鍵是樹狀結構的頁面View,因此程式代碼只需要檢查身分識別(也就是物件索引鍵和檢視都是一個和相同)。 以下列程式碼取代 IsViewFromObject

public override bool IsViewFromObject(View view, Java.Lang.Object obj)
{
    return view == obj;
}

將配接器新增至 ViewPager

現在已 TreePagerAdapter 實作 ,現在可以將它新增至 ViewPager。 在 MainActivity.cs中,將下列程式代碼行新增至 方法的 OnCreate 結尾:

viewPager.Adapter = new TreePagerAdapter(this, treeCatalog);

此程式代碼會具現化 TreePagerAdapter,傳入 MainActivity 做為內容 (this)。 具現化 TreeCatalog 會傳遞至建構函式的第二個自變數。 ViewPager屬性 Adapter 會設定為具現化TreePagerAdapter物件;這會將 插入 TreePagerAdapter ViewPager

核心實作現已完成 – 建置並執行應用程式。 您應該會看到樹狀目錄的第一個影像出現在畫面上,如下一個螢幕快照中的左側所示。 向左撥動以查看更多樹視圖,然後向右撥動以透過樹狀目錄移動:

TreePager 應用程式透過樹狀結構影像撥動的螢幕快照

新增呼叫器指標

這個最小 ViewPager 實作會顯示樹狀目錄的影像,但不會指出用戶位於目錄中的位置。 下一步驟是新增 PagerTabStrip。 會 PagerTabStrip 通知使用者要顯示哪個頁面,並藉由顯示上一頁和下一頁的提示來提供導覽內容。 PagerTabStrip 是要做為 目前頁面的 ViewPager指標;它會在使用者撥動每個頁面時捲動和更新。

開啟 Resources/layout/Main.axml ,並將 新增 PagerTabStrip 至版面配置:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.view.ViewPager
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/viewpager"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <android.support.v4.view.PagerTabStrip
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:layout_gravity="top"
          android:paddingBottom="10dp"
          android:paddingTop="10dp"
          android:textColor="#fff" />

</android.support.v4.view.ViewPager>

ViewPagerPagerTabStrip 的設計目的是一起運作。 當您在版面配置內ViewPager宣告 PagerTabStrip 時,ViewPager會自動尋找 PagerTabStrip 並將它連接到配接器。 當您建置並執行應用程式時,您應該會看到每個畫面頂端顯示的空白 PagerTabStrip

空白 PagerTabStrip 的關閉螢幕快照

顯示標題

若要將標題新增至每個頁面索引標籤,請在衍生類別中PagerAdapterGetPageTitleFormatted作 方法。 ViewPager 會呼叫 GetPageTitleFormatted (如果已實作),以取得描述位於指定位置之頁面的標題字串。 將下列方法新增至 TreePagerAdapter TreePagerAdapter.cs中的 類別:

public override Java.Lang.ICharSequence GetPageTitleFormatted(int position)
{
    return new Java.Lang.String(treeCatalog[position].caption);
}

此程式代碼會從樹狀目錄中的指定頁面(位置)擷取樹狀結構標題字串,將它轉換成 Java String,並將它傳回至 ViewPager。 當您使用這個新方法執行應用程式時,每個頁面都會在 中 PagerTabStrip顯示樹狀標題。 您應該會在畫面頂端看到樹狀結構名稱,但沒有底線:

具有文字填滿 PagerTabStrip 索引標籤之頁面的螢幕快照

您可以來回撥動以檢視目錄中每個標題樹狀結構影像。

PagerTitleStrip 變化

PagerTitleStrip 與 非常類似 PagerTabStrip ,不同之處在於為 PagerTabStrip 目前選取的索引標籤加上底線。您可以在上述版面設定中將 取代 PagerTabStrip PagerTitleStrip 為 ,然後再次執行應用程式,以查看其外觀 PagerTitleStrip

已從文字移除底線的PagerTitleStrip

請注意,當您轉換成 PagerTitleStrip時,會移除底線。

摘要

本逐步解說提供一個逐步範例,說明如何在不使用 Fragment的情況下建置基本ViewPager型應用程式。 它呈現了包含影像和標題字串的範例數據源、 ViewPager 顯示影像的配置,以及 PagerAdapter 連接到 ViewPager 數據源的子類別。 為了協助使用者瀏覽數據集,包含說明如何新增 PagerTabStripPagerTitleStrip 顯示每個頁面頂端影像標題的指示。