Rozszerzanie przykładu recyclerView
Podstawowa aplikacja opisana w przykładzie Podstawowego recyclerView nie robi zbyt wiele — po prostu przewija i wyświetla stałą listę elementów fotografii, aby ułatwić przeglądanie. W rzeczywistych aplikacjach użytkownicy oczekują, że będą mogli wchodzić w interakcję z aplikacją, naciskając elementy na ekranie. Ponadto bazowe źródło danych może ulec zmianie (lub zmienić przez aplikację), a zawartość ekranu musi pozostać spójna z tymi zmianami. W poniższych sekcjach dowiesz się, jak obsługiwać zdarzenia kliknięcia elementu i aktualizować je po zmianie RecyclerView
bazowego źródła danych.
Obsługa zdarzeń kliknięcia elementu
Gdy użytkownik dotknie elementu w elemencie RecyclerView
, zostanie wygenerowane zdarzenie kliknięcia elementu, aby powiadomić aplikację o tym, który element został dotknięty. To zdarzenie nie jest generowane przez RecyclerView
— zamiast tego widok elementu (który jest opakowany w uchwyt widoku) wykrywa dotknięcia i zgłasza te dotknięcia jako zdarzenia kliknięcia.
Aby zilustrować sposób obsługi zdarzeń kliknięcia elementu, poniższe kroki wyjaśniają, jak podstawowa aplikacja do wyświetlania zdjęć została zmodyfikowana w celu raportowania, które zdjęcie zostało poruszone przez użytkownika. Po wystąpieniu zdarzenia kliknięcia elementu w przykładowej aplikacji następuje następująca sekwencja:
CardView
Zdjęcie wykrywa zdarzenie kliknięcia elementu i powiadamia kartę.Adapter przekazuje zdarzenie (z informacjami o pozycji elementu) do programu obsługi elementów kliknij działanie.
Procedura obsługi kliknięcia elementu działania odpowiada na zdarzenie kliknięcia elementu.
Najpierw element członkowski procedury obsługi zdarzeń o nazwie ItemClick
jest dodawany do PhotoAlbumAdapter
definicji klasy:
public event EventHandler<int> ItemClick;
Następnie metoda obsługi zdarzeń kliknięcia elementu zostanie dodana do MainActivity
elementu .
Ten program obsługi krótko wyświetla wyskakujący wyskakujący element, który wskazuje, który element fotografii został dotknięty:
void OnItemClick (object sender, int position)
{
int photoNum = position + 1;
Toast.MakeText(this, "This is photo number " + photoNum, ToastLength.Short).Show();
}
Następnie potrzebny jest wiersz kodu do zarejestrowania programu obsługi za OnItemClick
pomocą PhotoAlbumAdapter
polecenia . Dobrym miejscem do wykonania jest natychmiast po PhotoAlbumAdapter
utworzeniu:
mAdapter = new PhotoAlbumAdapter (mPhotoAlbum);
mAdapter.ItemClick += OnItemClick;
W tym podstawowym przykładzie rejestracja programu obsługi odbywa się w metodzie głównej działania, ale aplikacja produkcyjna może zarejestrować program obsługi i wyrejestrowyć go w OnPause
OnResume
programie — zobacz Cykl życia działaniaOnCreate
, aby uzyskać więcej informacji.
PhotoAlbumAdapter
Funkcja będzie teraz wywoływana OnItemClick
po odebraniu zdarzenia kliknięcia elementu. Następnym krokiem jest utworzenie procedury obsługi w adapterze, która zgłasza to ItemClick
zdarzenie. Następująca metoda, OnClick
, jest dodawana natychmiast po metodzie adaptera ItemCount
:
void OnClick (int position)
{
if (ItemClick != null)
ItemClick (this, position);
}
Ta OnClick
metoda jest odbiornikiem adaptera dla zdarzeń kliknięcia elementu z widoków elementów. Przed zarejestrowaniem tego odbiornika w widoku elementu (za pośrednictwem uchwytu widoku elementu) należy zmodyfikować konstruktor, PhotoViewHolder
aby akceptował tę metodę jako dodatkowy argument i zarejestrował się OnClick
w zdarzeniu widoku Click
elementu.
Oto zmodyfikowany PhotoViewHolder
konstruktor:
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);
}
Parametr itemView
zawiera odwołanie do CardView
tego, którego dotyczył użytkownik. Należy pamiętać, że klasa bazowa uchwytu widoku zna położenie elementu (), który reprezentuje (CardView
za pośrednictwem LayoutPosition
właściwości), a ta pozycja jest przekazywana do metody adaptera OnClick
po wystąpieniu zdarzenia kliknięcia elementu. Metoda adaptera OnCreateViewHolder
jest modyfikowana w celu przekazania metody adaptera OnClick
do konstruktora uchwytu widoku:
PhotoViewHolder vh = new PhotoViewHolder (itemView, OnClick);
Teraz, gdy skompilujesz i uruchomisz przykładową aplikację do wyświetlania zdjęć, naciśnięcie zdjęcia na ekranie spowoduje wyświetlenie wyskakujących wyskakujących raportów, które zdjęcie zostało poruszone:
W tym przykładzie pokazano tylko jedno podejście do implementowania procedur obsługi zdarzeń za pomocą polecenia RecyclerView
. Innym podejściem, którego można użyć w tym miejscu, jest umieszczenie zdarzeń na posiadaczu widoku i subskrybowanie tych zdarzeń przez kartę. Jeśli przykładowa aplikacja do zdjęć dostarczyła możliwość edytowania zdjęć, oddzielne zdarzenia będą wymagane dla ImageView
elementu i TextView
w obrębie TextView
każdego CardView
elementu : spowoduje uruchomienie EditView
okna dialogowego umożliwiającego użytkownikowi edytowanie podpis i dotknięcie ImageView
spowoduje uruchomienie narzędzia do obsługi przydzieleń zdjęć, które pozwala użytkownikowi przycinać lub obracać zdjęcie. W zależności od potrzeb aplikacji należy zaprojektować najlepsze podejście do obsługi zdarzeń dotykowych i reagowania na nie.
Aby zademonstrować, jak RecyclerView
można zaktualizować po zmianie zestawu danych, przykładowa aplikacja do wyświetlania zdjęć może zostać zmodyfikowana w celu losowego wybrania zdjęcia w źródle danych i zamiany jej na pierwsze zdjęcie. Najpierw do przykładowego układu Main.axml aplikacji zdjęć jest dodawany przycisk Wyboru losowego:
<?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>
Następnie kod zostanie dodany na końcu metody działania OnCreate
głównego, aby zlokalizować Random Pick
przycisk w układzie i dołączyć do niego procedurę obsługi:
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();
}
};
Ta procedura obsługi wywołuje metodę albumu RandomSwap
fotograficznego po naciśnięciu przycisku Losowe wybieranie . Metoda RandomSwap
losowo zamienia zdjęcie z pierwszym zdjęciem w źródle danych, a następnie zwraca indeks losowo zamienionego zdjęcia. Po skompilowaniu i uruchomieniu przykładowej aplikacji za pomocą tego kodu naciśnięcie przycisku Wyboru losowego nie spowoduje zmiany wyświetlania, ponieważ RecyclerView
nie wiadomo o zmianie źródła danych.
Aby zachować RecyclerView
aktualizację po zmianie źródła danych, należy zmodyfikować procedurę obsługi klikania losowego, aby wywołać metodę karty NotifyItemChanged
dla każdego elementu w kolekcji, który uległ zmianie (w tym przypadku zmieniono dwa elementy: pierwsze zdjęcie i zamienione zdjęcie). RecyclerView
Powoduje to zaktualizowanie jego wyświetlania w taki sposób, aby był zgodny z nowym stanem źródła danych:
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);
}
};
Teraz po naciśnięciu przycisku Losowe wybieranie aktualizuje ekran, aby pokazać, RecyclerView
że zdjęcie w dalszej części kolekcji zostało zamienione na pierwsze zdjęcie w kolekcji:
Oczywiście NotifyDataSetChanged
można było wywołać metodę zamiast wykonywać dwa wywołania metody NotifyItemChanged
, ale wymusiłoby RecyclerView
to odświeżenie całej kolekcji, mimo że tylko dwa elementy w kolekcji uległy zmianie. Wywoływanie NotifyItemChanged
jest znacznie bardziej wydajne niż wywoływanie metody NotifyDataSetChanged
.