使用片段的 ViewPager
ViewPager 是一個版面配置管理員,可讓您實作 Gestural 流覽。 Gestural 瀏覽可讓使用者向左撥動和向右撥動,以逐步瀏覽數據頁面。 本指南說明如何使用 Fragments 作為數據頁,使用 ViewPager 實作可撥動 UI。
概觀
ViewPager
通常會與片段搭配使用,以便更輕鬆地管理 中 ViewPager
每個頁面的生命週期。 在本逐步解說中, ViewPager
用來建立名為 FlashCardPager 的應用程式,以在快閃卡上呈現一系列數學問題。 每個快閃卡都會實作為片段。 使用者透過快閃卡向左和向右撥動,並點選數學問題以顯示其答案。 此應用程式會 Fragment
為每個快閃卡建立實例,並實作衍生自 FragmentPagerAdapter
的配接器。 在 Viewpager 和 Views 中,大部分的工作都是在生命週期方法中 MainActivity
完成。 在 FlashCardPager 中,大部分的工作將由 在其其中一個生命週期方法中完成 Fragment
。
本指南並未涵蓋片段的基本概念 – 如果您還不熟悉 Xamarin.Android 中的片段,請參閱 片段 以協助您開始使用片段。
啟動應用程式專案
建立名為 FlashCardPager 的新 Android 專案。 接下來,啟動 NuGet 封裝管理員 (如需安裝 NuGet 套件的詳細資訊,請參閱逐步解說:在您的專案中包含 NuGet)。 尋找並安裝 Xamarin.Android.Support.v4 套件,如 Viewpager 和 Views 中所述。
新增範例數據源
在 FlashCardPager 中,數據源是類別所 FlashCardDeck
代表的快閃卡片組;此數據源會 ViewPager
提供項目內容。 FlashCardDeck
包含數學問題和解答的現成集合。 建 FlashCardDeck
構函式不需要自變數:
FlashCardDeck flashCards = new FlashCardDeck();
中的 FlashCardDeck
快閃卡片集合會組織,讓索引器可以存取每個快閃卡。 例如,下列程式代碼行會擷取甲板中的第四個快閃卡問題:
string problem = flashCardDeck[3].Problem;
這一行程式代碼會擷取上一個問題的對應答案:
string answer = flashCardDeck[3].Answer;
由於的 FlashCardDeck
實作詳細數據與了解 ViewPager
無關,因此此處並未列出程序 FlashCardDeck
代碼。
的原始程式碼FlashCardDeck
可在 FlashCardDeck.cs取得。
下載此原始程式檔(或將程式代碼複製並貼到新的 FlashCardDeck.cs 檔案中),並將其新增至您的專案。
建立 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;
using Android.Support.V4.App;
MainActivity
變更類別宣告,使其衍生自 FragmentActivity
:
public class MainActivity : FragmentActivity
MainActivity
衍生自FragmentActivity
(而非 Activity
),因為 FragmentActivity
知道如何管理片段的支援。 以下列程式碼取代 OnCreate
方法:
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.Main);
ViewPager viewPager = FindViewById<ViewPager>(Resource.Id.viewpager);
FlashCardDeck flashCards = new FlashCardDeck();
}
此程式碼會執行下列操作:
從 Main.axml 配置資源設定檢視。
從版面配置擷取 的參考
ViewPager
。將新的
FlashCardDeck
具現化為數據源。
當您建置並執行此程式代碼時,您應該會看到類似下列螢幕快照的顯示:
此時,ViewPager
是空的,因為它缺少使用的片段填入 ViewPager
,而且缺少從 FlashCardDeck 中的數據建立這些片段的配接器。
在下列各節中, FlashCardFragment
會建立 來實作每個快閃卡的功能,而 FragmentPagerAdapter
會建立 ,以將 連接到 ViewPager
從 中的數據建立的 FlashCardDeck
片段。
建立片段
每個快閃卡都會由稱為 FlashCardFragment
的UI片段管理。 FlashCardFragment
的檢視會顯示單一快閃卡所包含的資訊。 的每個實例 FlashCardFragment
都會由 ViewPager
裝載。
FlashCardFragment
的檢視將包含顯示 TextView
快閃卡問題文字的 。 此檢視會實作事件處理程式,該事件處理程式會在用戶點選快閃卡問題時使用 Toast
來顯示答案。
建立 FlashCardFragment 版面配置
必須先 FlashCardFragment
定義其配置,才能實作。 此配置是單一片段的片段容器配置。 將新的 Android 版面配置新增至名為 flashcard_layout.axml 的資源/版面配置。 開啟 Resources/layout/flashcard_layout.axml ,並以下列程式代碼取代其內容:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/flash_card_question"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:textAppearance="@android:style/TextAppearance.Large"
android:textSize="100sp"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="Question goes here" />
</RelativeLayout>
此配置會定義單一快閃卡片片段;每個片段都是由 , TextView
使用大型 (100sp) 字型來顯示數學問題。 此文字會在快閃卡上垂直和水準置中。
建立初始 FlashCardFragment 類別
新增名為 FlashCardFragment.cs 的新檔案,並以下列程式代碼取代其內容:
using System;
using Android.OS;
using Android.Views;
using Android.Widget;
using Android.Support.V4.App;
namespace FlashCardPager
{
public class FlashCardFragment : Android.Support.V4.App.Fragment
{
public FlashCardFragment() { }
public static FlashCardFragment newInstance(String question, String answer)
{
FlashCardFragment fragment = new FlashCardFragment();
return fragment;
}
public override View OnCreateView (
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View view = inflater.Inflate (Resource.Layout.flashcard_layout, container, false);
TextView questionBox = (TextView)view.FindViewById (Resource.Id.flash_card_question);
return view;
}
}
}
此程式代碼會存回將用來顯示快閃卡的基本 Fragment
定義。 請注意,FlashCardFragment
衍生自 中Android.Support.V4.App.Fragment
定義的支持連結庫版本Fragment
。 建構函式是空的 newInstance
,因此 Factory 方法可用來建立新的 FlashCardFragment
,而不是建構函式。
OnCreateView
生命週期方法會建立及設定 TextView
。 它會擴充片段的配置 TextView
,並將膨脹 TextView
傳回給呼叫端。 LayoutInflater
和 ViewGroup
會傳遞至 OnCreateView
,使其可以擴充版面配置。 套件savedInstanceState
組合包含用來從儲存狀態重新建立 TextView
的數據OnCreateView
。
片段的檢視是由的呼叫 inflater.Inflate
明確擴充。 自container
變數是檢視的父系,而 false
旗標會指示擴充器不要將擴充檢視新增至檢視的父系(稍後在本逐步解說中呼叫GetItem
配接器的方法時ViewPager
,將會新增它)。
將狀態代碼新增至 FlashCardFragment
如同活動,片段具有 Bundle
用來儲存和擷取其狀態的 。 在 FlashCardPager 中,這會 Bundle
用來儲存相關聯快閃卡的問答文字。 在 FlashCardFragment.cs中,將下列 Bundle
索引鍵新增至類別定義的頂端 FlashCardFragment
:
private static string FLASH_CARD_QUESTION = "card_question";
private static string FLASH_CARD_ANSWER = "card_answer";
newInstance
修改 Factory 方法,讓它建立 Bundle
物件,並使用上述索引鍵在具現化后,將傳遞的問答文字儲存在片段中:
public static FlashCardFragment newInstance(String question, String answer)
{
FlashCardFragment fragment = new FlashCardFragment();
Bundle args = new Bundle();
args.PutString(FLASH_CARD_QUESTION, question);
args.PutString(FLASH_CARD_ANSWER, answer);
fragment.Arguments = args;
return fragment;
}
修改片段生命週期方法OnCreateView
,從傳入的套件組合擷取這項資訊,並將問題文字載入 :TextBox
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
string question = Arguments.GetString(FLASH_CARD_QUESTION, "");
string answer = Arguments.GetString(FLASH_CARD_ANSWER, "");
View view = inflater.Inflate(Resource.Layout.flashcard_layout, container, false);
TextView questionBox = (TextView)view.FindViewById(Resource.Id.flash_card_question);
questionBox.Text = question;
return view;
}
answer
變數不會在這裡使用,但稍後會在事件處理程式程式代碼新增至此檔案時使用。
建立配接器
ViewPager
會使用位於 和數據源之間的 ViewPager
配接器控制器物件(請參閱 ViewPager 配 接器文章中的圖例)。
若要存取此數據, ViewPager
您必須提供衍生自 PagerAdapter
的自定義配接器。 由於此範例使用片段,因此會使用 FragmentPagerAdapter
- FragmentPagerAdapter
衍生自 PagerAdapter
。
FragmentPagerAdapter
表示每個頁面, Fragment
只要使用者可以返回頁面,就會持續保留在片段管理員中。 當使用者撥動 頁面 ViewPager
時,會 FragmentPagerAdapter
從資料源擷取資訊,並使用它來建立 Fragment
的 ViewPager
來顯示 。
當您實作 FragmentPagerAdapter
時,必須覆寫下列專案:
Count – 只讀屬性,可傳回可用的檢視數 (pages) 數目。
GetItem – 傳回要針對指定頁面顯示的片段。
新增名為 FlashCardDeckAdapter.cs 的新檔案,並以下列程式代碼取代其內容:
using System;
using Android.Views;
using Android.Widget;
using Android.Support.V4.App;
namespace FlashCardPager
{
class FlashCardDeckAdapter : FragmentPagerAdapter
{
public FlashCardDeckAdapter (Android.Support.V4.App.FragmentManager fm, FlashCardDeck flashCards)
: base(fm)
{
}
public override int Count
{
get { throw new NotImplementedException(); }
}
public override Android.Support.V4.App.Fragment GetItem(int position)
{
throw new NotImplementedException();
}
}
}
此程式代碼會存根基本 FragmentPagerAdapter
實作。 在下列各節中,這些方法都會取代為使用中的程序代碼。 建構函式的目的是將片段管理員傳遞至 FlashCardDeckAdapter
的基類建構函式。
實作配接器建構函式
當應用程式具現化 FlashCardDeckAdapter
時,它會提供片段管理員的參考,並具現化 FlashCardDeck
。
將下列成員變數新增至 類別頂 FlashCardDeckAdapter
端的 FlashCardDeckAdapter.cs:
public FlashCardDeck flashCardDeck;
將下列程式代碼列新增至建 FlashCardDeckAdapter
構函式:
this.flashCardDeck = flashCards;
這行程式代碼會儲存 將使用的 FlashCardDeck
FlashCardDeckAdapter
實例。
實作計數
實作 Count
相當簡單:它會傳回快閃卡片牌組中的快閃卡數目。 以下列程式碼取代 Count
:
public override int Count
{
get { return flashCardDeck.NumCards; }
}
的 NumCards
FlashCardDeck
屬性會傳回數據集中的快閃卡數(片段數目)。
實作 GetItem
方法 GetItem
會傳回與指定位置相關聯的片段。 當呼叫快閃卡片牌組中的位置時 GetItem
,它會傳回 設定 FlashCardFragment
為在該位置顯示快閃卡問題。 以下列程式碼取代 GetItem
方法:
public override Android.Support.V4.App.Fragment GetItem(int position)
{
return (Android.Support.V4.App.Fragment)
FlashCardFragment.newInstance (
flashCardDeck[position].Problem, flashCardDeck[position].Answer);
}
此程式碼會執行下列操作:
查閱甲板中指定位置的
FlashCardDeck
數學問題字串。查閱甲板中指定位置的
FlashCardDeck
回應字串。FlashCardFragment
呼叫 Factory 方法newInstance
,傳入快閃卡問題和回應字串。建立並傳回新的快閃卡片
Fragment
,其中包含該位置的問答文字。
當 呈現ViewPager
Fragment
於 position
時,它會顯示 TextBox
,其中包含位於position
快閃卡片牌組中的數學問題字串。
將配接器新增至 ViewPager
現在已 FlashCardDeckAdapter
實作 ,現在可以將它新增至 ViewPager
。 在 MainActivity.cs中,將下列程式代碼行新增至 方法的 OnCreate
結尾:
FlashCardDeckAdapter adapter =
new FlashCardDeckAdapter(SupportFragmentManager, flashCards);
viewPager.Adapter = adapter;
此程式代碼會具現化 FlashCardDeckAdapter
,傳入 SupportFragmentManager
第一個自變數中的 。 SupportFragmentManager
(FragmentActivity 的 屬性是用來取得 的FragmentManager
參考 – 如需 的詳細資訊FragmentManager
,請參閱管理片段。
核心實作現已完成 – 建置並執行應用程式。 您應該會看到快閃卡片牌組的第一張影像出現在畫面上,如下一個螢幕快照中的左側所示。 向左撥動以查看更多快閃卡片,然後向右撥動以透過快閃卡片牌組移動:
新增呼叫器指標
這個最小 ViewPager
實作會顯示甲板中的每個快閃卡片,但不會指出用戶位於甲板內的位置。 下一步驟是新增 PagerTabStrip
。 會 PagerTabStrip
通知使用者要顯示哪個問題號碼,並藉由顯示上一個和下一個快閃卡的提示來提供瀏覽內容。
開啟 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/pager"
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>
當您建置並執行應用程式時,應該會看到每個快閃卡頂端顯示的空白 PagerTabStrip
:
顯示標題
若要將標題新增至每個頁面索引標籤,請在配接器中實 GetPageTitleFormatted
作 方法。 ViewPager
會呼叫 GetPageTitleFormatted
(如果已實作),以取得描述位於指定位置之頁面的標題字串。 將下列方法新增至 FlashCardDeckAdapter
FlashCardDeckAdapter.cs 中的 類別:
public override Java.Lang.ICharSequence GetPageTitleFormatted(int position)
{
return new Java.Lang.String("Problem " + (position + 1));
}
此程式代碼會將快閃卡片牌組中的位置轉換為問題編號。 產生的字串會轉換成傳回至的ViewPager
JavaString
。 當您使用這個新方法執行應用程式時,每個頁面都會在 中 PagerTabStrip
顯示問題號碼:
您可以來回撥動,以查看每張快閃卡片頂端所顯示的快閃卡片牌組中的問題號碼。
處理使用者輸入
FlashCardPager 會在 中 ViewPager
呈現一系列的片段式快閃卡,但它還沒有辦法顯示每個問題的答案。 在本節中,當用戶點選快閃卡問題文字時,會將事件處理程式新增至 FlashCardFragment
,以顯示答案。
開啟 FlashCardFragment.cs,並在 檢視傳回給呼叫端之前,將下列程式代碼新增至 方法的 OnCreateView
結尾:
questionBox.Click += delegate
{
Toast.MakeText(Activity.ApplicationContext,
"Answer: " + answer, ToastLength.Short).Show();
};
此 Click
事件處理程式會在用戶點選 TextBox
時出現的快顯通知中顯示答案。 answer
當狀態資訊從傳遞至 OnCreateView
的套件組合讀取時,變數會稍早初始化。 建置並執行應用程式,然後點選每個快閃卡上的問題文字以查看答案:
本逐步解說中顯示的 FlashCardPager 使用MainActivity
衍生自 FragmentActivity
,但您也可以衍生MainActivity
自 AppCompatActivity
(這也提供管理片段的支援)。
摘要
本逐步解說提供如何使用 s 建置基本 ViewPager
型應用程式的 Fragment
逐步範例。 它呈現了包含快閃卡問題和解答的範例數據源、 ViewPager
顯示快閃卡的配置,以及 FragmentPagerAdapter
聯機 ViewPager
至數據源的子類別。 為了協助用戶流覽快閃卡,包含說明如何新增 PagerTabStrip
以在每個頁面頂端顯示問題號碼的指示。 最後,新增事件處理程序代碼,以在用戶點選快閃卡問題時顯示答案。