基本回收工具檢視範例
若要瞭解一般應用程式中的運作方式 RecyclerView
,本主題會探索用來顯示大量相片集合的簡單程式代碼範例 RecyclerView
:
RecyclerViewer 會使用 CardView 在版面配置中實作 RecyclerView
每個相片專案。 RecyclerView
由於效能優點,此範例應用程式能夠順暢且不會明顯延遲地快速捲動大型相片集合。
數據源範例
在此範例應用程式中,「相簿」數據源(由 PhotoAlbum
類別表示)會 RecyclerView
提供項目內容。
PhotoAlbum
是具有標題的相片集合;當您具現化它時,您會收到 32 張照片的現成集合:
PhotoAlbum mPhotoAlbum = new PhotoAlbum ();
中的每個PhotoAlbum
相片實例都會公開屬性,讓您讀取其影像資源識別碼,PhotoID
以及其標題字串 。 Caption
相片的集合會組織,讓每個相片都可以由索引器存取。 例如,下列幾行程式代碼會存取集合中第十張照片的影像資源標識碼和標題:
int imageId = mPhotoAlbum[9].ImageId;
string caption = mPhotoAlbum[9].Caption;
PhotoAlbum
也提供 RandomSwap
方法,您可以呼叫 來將集合中的第一張相片交換為集合中其他位置的隨機選擇相片:
mPhotoAlbum.RandomSwap ();
由於的 PhotoAlbum
實作詳細數據與了解 RecyclerView
無關, PhotoAlbum
因此此處不會顯示原始程式碼。
版面配置和初始化
設定檔案 Main.axml 是由 中的LinearLayout
單RecyclerView
一所組成:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:scrollbars="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</LinearLayout>
請注意,您必須使用完整名稱 android.support.v7.widget.RecyclerView ,因為 RecyclerView
已封裝在支持連結庫中。 初始化 OnCreate
此配置的方法 MainActivity
、具現化配接器,並準備基礎數據源:
public class MainActivity : Activity
{
RecyclerView mRecyclerView;
RecyclerView.LayoutManager mLayoutManager;
PhotoAlbumAdapter mAdapter;
PhotoAlbum mPhotoAlbum;
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
// Prepare the data source:
mPhotoAlbum = new PhotoAlbum ();
// Instantiate the adapter and pass in its data source:
mAdapter = new PhotoAlbumAdapter (mPhotoAlbum);
// Set our view from the "main" layout resource:
SetContentView (Resource.Layout.Main);
// Get our RecyclerView layout:
mRecyclerView = FindViewById<RecyclerView> (Resource.Id.recyclerView);
// Plug the adapter into the RecyclerView:
mRecyclerView.SetAdapter (mAdapter);
此程式碼會執行下列操作:
具現化
PhotoAlbum
數據源。將相簿數據源傳遞至配接器的建構函式(
PhotoAlbumAdapter
本指南稍後定義)。 請注意,最佳做法是將數據源當做參數傳遞至配接器的建構函式。RecyclerView
從版面設定取得 。呼叫 方法,將配接器插入 實例,
RecyclerView
RecyclerView
SetAdapter
如上所示。
版面配置管理員
中的每個RecyclerView
CardView
專案都是由 包含相片影像和相片標題的 組成(下方檢視持有人區段涵蓋詳細數據)。 預先定義的 LinearLayoutManager
是用來以垂直捲動排列方式設定每個 CardView
配置:
mLayoutManager = new LinearLayoutManager (this);
mRecyclerView.SetLayoutManager (mLayoutManager);
此程式代碼位於主要活動的方法中 OnCreate
。 設定管理員的建構函式需要 內容,因此 MainActivity
會使用 this
如上所示傳遞 。
您可以插入自訂版面配置管理員,以並排顯示兩CardView
個項目,實作翻頁動畫效果來周遊相片集合,而不是使用預先LinearLayoutManager
定義的 。 稍後在本指南中,您將會看到如何在不同版面配置管理員中交換來修改版面配置的範例。
檢視持有人
檢視持有者類別稱為 PhotoViewHolder
。 每個PhotoViewHolder
實例都會保存關聯數據列項目的 參考ImageView
TextView
,其配置CardView
如下圖所示:
PhotoViewHolder
衍生自 RecyclerView.ViewHolder
,並包含屬性,以儲存上述版面配置中顯示的 和 TextView
參考ImageView
。
PhotoViewHolder
由兩個屬性和一個建構函式所組成:
public class PhotoViewHolder : RecyclerView.ViewHolder
{
public ImageView Image { get; private set; }
public TextView Caption { get; private set; }
public PhotoViewHolder (View itemView) : base (itemView)
{
// Locate and cache view references:
Image = itemView.FindViewById<ImageView> (Resource.Id.imageView);
Caption = itemView.FindViewById<TextView> (Resource.Id.textView);
}
}
在這裡程式代碼範例中,建PhotoViewHolder
構函式會傳遞包裝之父項目檢視的參考。PhotoViewHolder
CardView
請注意,您一律會將父項目檢視轉送至基底建構函式。 建PhotoViewHolder
構函式會呼叫FindViewById
父項目檢視,以找出其每個子檢視參考,ImageView
並將TextView
結果分別儲存在 和 Caption
屬性中Image
。 配接器稍後會從這些屬性擷取檢視參考,以新的數據更新這個 CardView
子檢視。
如需 的詳細資訊 RecyclerView.ViewHolder
,請參閱 RecyclerView.ViewHolder 類別參考。
配接器
配接器會載入每個 RecyclerView
數據列,其中包含特定相片的數據。 例如,對於位於數據列位置 P 的指定相片,配接器會在數據源內的位置 P 找到相關聯的數據,並將此數據複製到集合中RecyclerView
位於 P 位置的數據列專案。 配接器會使用檢視持有者來查閱 和 TextView
的參考ImageView
,因此當使用者捲動相片集合並重複使用檢視時,不需要重複呼叫FindViewById
這些檢視。
在 RecyclerViewer 中,配接器類別衍生自 RecyclerView.Adapter
以建立 PhotoAlbumAdapter
:
public class PhotoAlbumAdapter : RecyclerView.Adapter
{
public PhotoAlbum mPhotoAlbum;
public PhotoAlbumAdapter (PhotoAlbum photoAlbum)
{
mPhotoAlbum = photoAlbum;
}
...
}
成員 mPhotoAlbum
包含傳入建構函式的數據源(相簿),建構函式會將相簿複製到這個成員變數。 已實作下列必要 RecyclerView.Adapter
方法:
OnCreateViewHolder
– 具現化專案配置檔案和檢視持有者。OnBindViewHolder
– 將位於指定位置的數據載入至參考儲存在指定檢視持有者中的檢視中。ItemCount
– 傳回數據源中的項目數。
配置管理員會在將專案放置在 內 RecyclerView
時呼叫這些方法。 下列各節會檢查這些方法的實作。
OnCreateViewHolder
當 需要新的檢視持有者來代表專案時,RecyclerView
配置管理員會呼叫 OnCreateViewHolder
。 OnCreateViewHolder
從檢視的配置檔案擴充項目檢視,並將檢視包裝在新實例中 PhotoViewHolder
。 建PhotoViewHolder
構函式會尋找並儲存配置中子檢視的參考,如檢視持有人先前所述。
每個數據列專案都以 CardView
ImageView
包含 (針對相片) 和 TextView
(標題) 的 來表示。 此設定位於 PhotoCardView.axml 檔案中:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:card_view="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
card_view:cardElevation="4dp"
card_view:cardUseCompatPadding="true"
card_view:cardCornerRadius="5dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="8dp">
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/imageView"
android:scaleType="centerCrop" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="#333333"
android:text="Caption"
android:id="@+id/textView"
android:layout_gravity="center_horizontal"
android:layout_marginLeft="4dp" />
</LinearLayout>
</android.support.v7.widget.CardView>
</FrameLayout>
此配置代表 中的 RecyclerView
單一數據列專案。 方法 OnBindViewHolder
(如下所述)會將資料來源 ImageView
中的資料複製到此版面設定的 與 TextView
。
OnCreateViewHolder
在 中RecyclerView
為指定相片位置擴充此版面配置,並具現化新的 PhotoViewHolder
實例(這會在相關聯的CardView
版面配置中尋找和快取與TextView
子檢視的參考ImageView
):
public override RecyclerView.ViewHolder
OnCreateViewHolder (ViewGroup parent, int viewType)
{
// Inflate the CardView for the photo:
View itemView = LayoutInflater.From (parent.Context).
Inflate (Resource.Layout.PhotoCardView, parent, false);
// Create a ViewHolder to hold view references inside the CardView:
PhotoViewHolder vh = new PhotoViewHolder (itemView);
return vh;
}
產生的檢視持有者實例 vh
會傳回給呼叫端(配置管理員)。
OnBindViewHolder
當配置管理員準備好在可見的畫面區域中顯示特定檢視 RecyclerView
時,它會呼叫配接器 OnBindViewHolder
的方法,以數據源中的內容填滿指定數據列位置的專案。 OnBindViewHolder
會取得指定數據列位置的相片資訊(相片的影像資源和相片標題的字串),並將此數據複製到相關聯的檢視。 檢視是透過儲存在檢視持有者物件中的參考來找到(透過 參數傳入 holder
):
public override void
OnBindViewHolder (RecyclerView.ViewHolder holder, int position)
{
PhotoViewHolder vh = holder as PhotoViewHolder;
// Load the photo image resource from the photo album:
vh.Image.SetImageResource (mPhotoAlbum[position].PhotoID);
// Load the photo caption from the photo album:
vh.Caption.Text = mPhotoAlbum[position].Caption;
}
傳入的檢視持有者對象必須先轉換成衍生檢視持有者類型(在此案例中為 PhotoViewHolder
),才能使用。
配接器會將影像資源載入檢視持有人的 Image
屬性所參考的檢視中,並將標題文字複製到檢視持有者屬性所參考的 Caption
檢視中。 這會 系結 相關聯的檢視與其數據。
請注意, OnBindViewHolder
是直接處理數據結構的程序代碼。 在此情況下, OnBindViewHolder
瞭解如何將 RecyclerView
專案位置對應至數據源中的相關聯數據項。 在此情況下,對應很簡單,因為位置可以當做相簿的陣列索引使用;不過,更複雜的數據源可能需要額外的程式代碼才能建立這類對應。
ItemCount
方法 ItemCount
會傳回數據收集中的項目數。 在範例相片檢視器應用程式中,專案計數是相簿中的相片數目:
public override int ItemCount
{
get { return mPhotoAlbum.NumPhotos; }
}
如需 的詳細資訊 RecyclerView.Adapter
,請參閱 RecyclerView.Adapter 類別參考。
把它全部放在一起
範例相片應用程式所產生的 RecyclerView
實作是由 MainActivity
建立數據源、版面配置管理員和配接器的程式代碼所組成。 MainActivity
建立 mRecyclerView
實例、具現化數據源和配接器,並插入配置管理員和配接器:
public class MainActivity : Activity
{
RecyclerView mRecyclerView;
RecyclerView.LayoutManager mLayoutManager;
PhotoAlbumAdapter mAdapter;
PhotoAlbum mPhotoAlbum;
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
mPhotoAlbum = new PhotoAlbum();
SetContentView (Resource.Layout.Main);
mRecyclerView = FindViewById<RecyclerView> (Resource.Id.recyclerView);
// Plug in the linear layout manager:
mLayoutManager = new LinearLayoutManager (this);
mRecyclerView.SetLayoutManager (mLayoutManager);
// Plug in my adapter:
mAdapter = new PhotoAlbumAdapter (mPhotoAlbum);
mRecyclerView.SetAdapter (mAdapter);
}
}
PhotoViewHolder
會尋找並快取檢視參考:
public class PhotoViewHolder : RecyclerView.ViewHolder
{
public ImageView Image { get; private set; }
public TextView Caption { get; private set; }
public PhotoViewHolder (View itemView) : base (itemView)
{
// Locate and cache view references:
Image = itemView.FindViewById<ImageView> (Resource.Id.imageView);
Caption = itemView.FindViewById<TextView> (Resource.Id.textView);
}
}
PhotoAlbumAdapter
會實作三個必要方法覆寫:
public class PhotoAlbumAdapter : RecyclerView.Adapter
{
public PhotoAlbum mPhotoAlbum;
public PhotoAlbumAdapter (PhotoAlbum photoAlbum)
{
mPhotoAlbum = photoAlbum;
}
public override RecyclerView.ViewHolder
OnCreateViewHolder (ViewGroup parent, int viewType)
{
View itemView = LayoutInflater.From (parent.Context).
Inflate (Resource.Layout.PhotoCardView, parent, false);
PhotoViewHolder vh = new PhotoViewHolder (itemView);
return vh;
}
public override void
OnBindViewHolder (RecyclerView.ViewHolder holder, int position)
{
PhotoViewHolder vh = holder as PhotoViewHolder;
vh.Image.SetImageResource (mPhotoAlbum[position].PhotoID);
vh.Caption.Text = mPhotoAlbum[position].Caption;
}
public override int ItemCount
{
get { return mPhotoAlbum.NumPhotos; }
}
}
編譯並執行此程式代碼時,它會建立基本相片檢視應用程式,如下列螢幕快照所示:
如果未繪製陰影(如上述螢幕快照所示),請編輯 Properties/AndroidManifest.xml ,並將下列屬性設定新增至 <application>
元素:
android:hardwareAccelerated="true"
此基本應用程式僅支援瀏覽相簿。 它不會回應項目觸控事件,也不會處理基礎數據中的變更。 這項功能會在擴充 RecyclerView 範例中新增。
變更 LayoutManager
RecyclerView
因為彈性,所以很容易修改應用程式以使用不同的版面配置管理員。 在下列範例中,它會修改成使用水平捲動而非垂直線性版面配置來顯示相簿。 若要這樣做,版面配置管理員具現化會修改為使用 , GridLayoutManager
如下所示:
mLayoutManager = new GridLayoutManager(this, 2, GridLayoutManager.Horizontal, false);
此程式代碼變更會將 垂直LinearLayoutManager
GridLayoutManager
取代為 ,其呈現由兩個數據列組成的網格線,而數據列會以水準方向卷動。 當您再次編譯並執行應用程式時,您會看到相片會顯示在網格線中,而且捲動是水準而非垂直的:
只要變更一行程序代碼,就可以修改相片檢視應用程式,以使用不同的配置與不同的行為。 請注意,不需要修改配接器程式代碼或配置 XML 來變更版面配置樣式。
在下一個主題中, 擴充 RecyclerView 範例,此基本範例應用程式會擴充以處理項目點擊事件,並在基礎數據源變更時更新 RecyclerView
。