使用檢視的 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:
這也會安裝 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();
}
此程式碼會執行下列操作:
從 Main.axml 配置資源設定檢視。
從版面配置擷取 的參考
ViewPager
。將新的
TreeCatalog
具現化為數據源。
當您建置並執行此程式代碼時,您應該會看到類似下列螢幕快照的顯示:
此時,是空的ViewPager
,因為它缺少用來存取 TreeCatalog 中內容的配接器。 在下一 節中,會建立 PagerAdapter 以連線 ViewPager
到 TreeCatalog。
建立配接器
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;
}
此程式碼會執行下列操作:
具現化新的
ImageView
,以顯示位於指定位置的樹狀結構影像。 應用程式的MainActivity
是將傳遞至ImageView
建構函式的內容。將
ImageView
資源設定為TreeCatalog
位於指定位置的影像資源標識碼。將傳遞的容器
View
ViewPager
轉換為參考。 請注意,您必須使用JavaCast<ViewPager>()
來正確執行此轉換(這是必要的,讓 Android 執行運行時間檢查的類型轉換)。將 具現化
ImageView
的 加入至ViewPager
,並將 傳回ImageView
給呼叫端。
顯示位於ViewPager
position
影像時,會顯示這個 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);
}
此程式碼會執行下列操作:
將傳遞的容器
View
轉換成ViewPager
參考。將傳遞的 Java 物件 (
view
) 轉換成 C#View
(view as View
):從
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
。
核心實作現已完成 – 建置並執行應用程式。 您應該會看到樹狀目錄的第一個影像出現在畫面上,如下一個螢幕快照中的左側所示。 向左撥動以查看更多樹視圖,然後向右撥動以透過樹狀目錄移動:
新增呼叫器指標
這個最小 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>
ViewPager
和 PagerTabStrip
的設計目的是一起運作。 當您在版面配置內ViewPager
宣告 PagerTabStrip
時,ViewPager
會自動尋找 PagerTabStrip
並將它連接到配接器。 當您建置並執行應用程式時,您應該會看到每個畫面頂端顯示的空白 PagerTabStrip
:
顯示標題
若要將標題新增至每個頁面索引標籤,請在衍生類別中PagerAdapter
實GetPageTitleFormatted
作 方法。 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
顯示樹狀標題。 您應該會在畫面頂端看到樹狀結構名稱,但沒有底線:
您可以來回撥動以檢視目錄中每個標題樹狀結構影像。
PagerTitleStrip 變化
PagerTitleStrip
與 非常類似 PagerTabStrip
,不同之處在於為 PagerTabStrip
目前選取的索引標籤加上底線。您可以在上述版面設定中將 取代 PagerTabStrip
PagerTitleStrip
為 ,然後再次執行應用程式,以查看其外觀 PagerTitleStrip
:
請注意,當您轉換成 PagerTitleStrip
時,會移除底線。
摘要
本逐步解說提供一個逐步範例,說明如何在不使用 Fragment
的情況下建置基本ViewPager
型應用程式。 它呈現了包含影像和標題字串的範例數據源、 ViewPager
顯示影像的配置,以及 PagerAdapter
連接到 ViewPager
數據源的子類別。 為了協助使用者瀏覽數據集,包含說明如何新增 PagerTabStrip
或 PagerTitleStrip
顯示每個頁面頂端影像標題的指示。