擴充 RecyclerView 範例
基本回收工具檢視範例中所述的基本應用程式實際上不會執行太多動作,它只會捲動並顯示固定的照片項目清單,以方便流覽。 在真實世界中,用戶預期能夠藉由點選顯示器中的專案來與應用程式互動。 此外,基礎數據源可以變更(或由應用程式變更),而且顯示的內容必須與這些變更保持一致。 在下列各節中,您將瞭解如何處理專案點選事件,並在基礎數據源變更時更新 RecyclerView
。
處理項目點擊事件
當使用者觸碰 中的 RecyclerView
專案時,會產生專案點選事件,以通知應用程式觸控到哪個專案。 此事件不是由 RecyclerView
產生 –相反地,項目檢視(包裝在檢視持有者中)會偵測觸控,並將這些觸控報告為點選事件。
為了說明如何處理項目點擊事件,下列步驟說明如何修改基本相片檢視應用程式,以報告用戶已觸及哪些相片。 在範例應用程式中發生項目按兩下列順序:
相片會
CardView
偵測到項目點擊事件,並通知適配卡。配接器會將事件 (具有專案位置資訊) 轉送至活動的item-click 處理程式。
活動的item-click 處理程式會響應項目點選事件。
首先,名為 ItemClick
的 PhotoAlbumAdapter
事件處理程式成員會新增至類別定義:
public event EventHandler<int> ItemClick;
接下來,項目按下事件處理程式方法會新增至 MainActivity
。
此處理程式會簡短地顯示快顯通知,指出哪些相片專案已觸碰:
void OnItemClick (object sender, int position)
{
int photoNum = position + 1;
Toast.MakeText(this, "This is photo number " + photoNum, ToastLength.Short).Show();
}
接下來,需要一行程序代碼,才能向 PhotoAlbumAdapter
註冊OnItemClick
處理程式。 建立之後 PhotoAlbumAdapter
,就會立即完成此動作:
mAdapter = new PhotoAlbumAdapter (mPhotoAlbum);
mAdapter.ItemClick += OnItemClick;
在此基本範例中,處理程式註冊會在主要活動的 OnCreate
方法中進行,但生產應用程式可能會在 中 OnResume
註冊處理程式,並將其取消註冊 OnPause
– 如需詳細資訊,請參閱 活動生命週期 。
PhotoAlbumAdapter
現在會在收到項目點選取事件時呼叫 OnItemClick
。 下一個步驟是在引發此 ItemClick
事件的配接器中建立處理程式。 下列方法會在配接器的 ItemCount
方法OnClick
之後立即新增:
void OnClick (int position)
{
if (ItemClick != null)
ItemClick (this, position);
}
此方法OnClick
是配接器的接聽程式,用於項目檢視中的項目點選事件。 在向項目檢視註冊此接聽程式之前(透過項目檢視的檢視持有者),PhotoViewHolder
建構函式必須先修改才能接受此方法做為其他自變數,然後向項目檢視Click
事件註冊OnClick
。
以下是修改過的 PhotoViewHolder
建構函式:
public PhotoViewHolder (View itemView, Action<int> listener)
: base (itemView)
{
Image = itemView.FindViewById<ImageView> (Resource.Id.imageView);
Caption = itemView.FindViewById<TextView> (Resource.Id.textView);
itemView.Click += (sender, e) => listener (base.LayoutPosition);
}
參數 itemView
包含使用者所觸碰的 參考 CardView
。 請注意,檢視持有者基類知道專案 () 的版面配置位置,表示它 (CardView
透過 LayoutPosition
屬性),而且當專案點擊事件發生時,這個位置會傳遞至配接器 OnClick
的方法。 配接器的方法會修改為將配 OnCreateViewHolder
接器 OnClick
的方法傳遞至檢視持有者的建構函式:
PhotoViewHolder vh = new PhotoViewHolder (itemView, OnClick);
現在,當您建置並執行範例相片檢視應用程式時,點選顯示器中的相片會導致快顯通知顯示該報表所碰到相片:
此範例只示範一個使用 實作事件處理程式 RecyclerView
的方法。 這裡可以使用的另一種方法是將事件放在檢視持有者上,並讓配接器訂閱這些事件。 如果範例相片應用程式提供相片編輯功能,則會針對 ImageView
和內的個別CardView
事件:觸控 TextView
會啟動對話框,讓使用者編輯 標題,而 ImageView
觸控 會啟動EditView
相片觸控工具,讓使用者裁剪TextView
或旋轉相片。 根據應用程式的需求,您必須設計處理和回應觸控事件的最佳方法。
為了示範如何在 RecyclerView
數據集變更時更新,可以修改範例相片檢視應用程式,以隨機挑選數據源中的相片,並將它與第一張相片交換。 首先, 隨機挑選 按鈕會新增至範例相片應用程式的 Main.axml 版面配置:
<?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">
<Button
android:id="@+id/randPickButton"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Random Pick" />
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:scrollbars="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</LinearLayout>
接下來,會在主要活動 OnCreate
方法的結尾新增程序代碼,以找出 Random Pick
配置中的按鈕,並將處理程式附加至其中:
Button randomPickBtn = FindViewById<Button>(Resource.Id.randPickButton);
randomPickBtn.Click += delegate
{
if (mPhotoAlbum != null)
{
// Randomly swap a photo with the first photo:
int idx = mPhotoAlbum.RandomSwap();
}
};
當點選 [隨機挑選] 按鈕時,這個處理程式會呼叫相簿的 RandomSwap
方法。 方法 RandomSwap
會隨機交換相片與數據源中的第一張相片,然後傳回隨機交換相片的索引。 當您使用此程式碼編譯和執行範例應用程式時,點選 [ 隨機選擇 ] 按鈕不會產生顯示變更,因為 RecyclerView
不知道數據源的變更。
若要在數據源變更后保持 RecyclerView
更新, 必須修改隨機選擇 單擊處理程式,以針對集合中已變更的每個專案呼叫配接器 NotifyItemChanged
的方法(在此案例中,有兩個專案已變更:第一張相片和交換的相片)。 這會導致 RecyclerView
更新其顯示,使其與數據源的新狀態一致:
Button randomPickBtn = FindViewById<Button>(Resource.Id.randPickButton);
randomPickBtn.Click += delegate
{
if (mPhotoAlbum != null)
{
int idx = mPhotoAlbum.RandomSwap();
// First photo has changed:
mAdapter.NotifyItemChanged(0);
// Swapped photo has changed:
mAdapter.NotifyItemChanged(idx);
}
};
現在,當點選 [ 隨機選擇 ] 按鈕時, RecyclerView
更新顯示器以顯示集合中進一步關閉相片已與集合中的第一張相片交換:
當然, NotifyDataSetChanged
可以呼叫 而不是呼叫這兩個 , NotifyItemChanged
但這樣做會強制 RecyclerView
重新整理整個集合,即使集合中只有兩個專案已經變更。 呼叫 NotifyItemChanged
比呼叫 NotifyDataSetChanged
更有效率。