Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
L'app di base descritta in A Basic RecyclerView Example in realtà non esegue molto: scorre semplicemente e visualizza un elenco fisso di elementi fotografici per facilitare l'esplorazione. Nelle applicazioni reali, gli utenti si aspettano di poter interagire con l'app toccando gli elementi nella visualizzazione. Inoltre, l'origine dati sottostante può cambiare (o essere modificata dall'app) e il contenuto della visualizzazione deve rimanere coerente con queste modifiche. Nelle sezioni seguenti si apprenderà come gestire gli eventi di clic sugli elementi e aggiornare RecyclerView
quando viene modificata l'origine dati sottostante.
Gestione degli eventi Item-Click
Quando un utente tocca un elemento in RecyclerView
, viene generato un evento di clic su un elemento per notificare all'app come a quale elemento è stato toccato. Questo evento non viene generato da RecyclerView
, ma la visualizzazione dell'elemento (di cui è stato eseguito il wrapping nel supporto della visualizzazione) rileva i tocco e segnala questi tocchi come eventi di clic.
Per illustrare come gestire gli eventi di clic sugli elementi, i passaggi seguenti illustrano come l'app di visualizzazione foto di base viene modificata per segnalare quale fotografia è stata toccata dall'utente. Quando si verifica un evento item-click nell'app di esempio, viene eseguita la sequenza seguente:
La fotografia rileva l'evento
CardView
item-click e invia una notifica all'adattatore.L'adattatore inoltra l'evento (con informazioni sulla posizione dell'elemento) al gestore di clic dell'elemento dell'attività.
Il gestore di clic sugli elementi dell'attività risponde all'evento item-click.
Prima di tutto, un membro del gestore eventi chiamato ItemClick
viene aggiunto alla definizione della PhotoAlbumAdapter
classe:
public event EventHandler<int> ItemClick;
Successivamente, viene aggiunto un metodo del gestore eventi item-click a MainActivity
.
Questo gestore visualizza brevemente un avviso popup che indica quale elemento fotografico è stato toccato:
void OnItemClick (object sender, int position)
{
int photoNum = position + 1;
Toast.MakeText(this, "This is photo number " + photoNum, ToastLength.Short).Show();
}
Successivamente, è necessaria una riga di codice per registrare il OnItemClick
gestore con PhotoAlbumAdapter
. Un buon posto per eseguire questa operazione è immediatamente dopo PhotoAlbumAdapter
la creazione:
mAdapter = new PhotoAlbumAdapter (mPhotoAlbum);
mAdapter.ItemClick += OnItemClick;
In questo esempio di base la registrazione del gestore viene eseguita nel metodo dell'attività OnCreate
principale, ma un'app di produzione potrebbe registrare il gestore in OnResume
e annullarne OnPause
la registrazione. Per altre informazioni, vedere Ciclo di vita delle attività.
PhotoAlbumAdapter
chiamerà ora OnItemClick
quando riceve un evento item-click. Il passaggio successivo consiste nel creare un gestore nell'adapter che genera questo ItemClick
evento. Il metodo seguente, OnClick
, viene aggiunto immediatamente dopo il metodo dell'adapter ItemCount
:
void OnClick (int position)
{
if (ItemClick != null)
ItemClick (this, position);
}
Questo OnClick
metodo è il listener dell'adapter per gli eventi di clic sugli elementi dalle visualizzazioni degli elementi. Prima che questo listener possa essere registrato con una visualizzazione elemento (tramite il supporto di visualizzazione della visualizzazione dell'elemento), il PhotoViewHolder
costruttore deve essere modificato per accettare questo metodo come argomento aggiuntivo e registrarsi OnClick
con l'evento di visualizzazione Click
elementi.
Ecco il costruttore modificato 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);
}
Il itemView
parametro contiene un riferimento all'oggetto CardView
che è stato toccato dall'utente. Si noti che la classe base del supporto visualizzazione conosce la posizione di layout dell'elemento (CardView
) che rappresenta (tramite la LayoutPosition
proprietà ) e questa posizione viene passata al metodo dell'adattatore OnClick
quando si verifica un evento di clic su un elemento. Il metodo dell'adattatore OnCreateViewHolder
viene modificato per passare il metodo dell'adattatore OnClick
al costruttore del titolare della visualizzazione:
PhotoViewHolder vh = new PhotoViewHolder (itemView, OnClick);
Ora, quando crei ed esegui l'app di esempio di visualizzazione foto, toccando una foto nella visualizzazione verrà visualizzato un avviso popup che segnala che la fotografia è stata toccata:
In questo esempio viene illustrato un solo approccio per l'implementazione di gestori eventi con RecyclerView
. Un altro approccio che può essere usato in questo caso consiste nell'inserire eventi nel supporto della visualizzazione e fare in modo che l'adattatore sottoscriva questi eventi. Se l'app foto di esempio ha fornito una funzionalità di modifica delle foto, sarebbero necessari eventi separati per ImageView
e TextView
all'interno di ogni CardView
: i tocchi sull'oggetto TextView
avviano una EditView
finestra di dialogo che consente all'utente di modificare il didascalia e toccando l'oggetto ImageView
avvia uno strumento di touchup fotografico che consente all'utente di ritagliare o ruotare la foto. A seconda delle esigenze dell'app, devi progettare l'approccio migliore per la gestione e la risposta agli eventi di tocco.
Per dimostrare come RecyclerView
può essere aggiornato quando il set di dati cambia, l'app di visualizzazione foto di esempio può essere modificata per selezionare in modo casuale una foto nell'origine dati e scambiarla con la prima foto. Prima di tutto, viene aggiunto un pulsante Selezione casuale al layout Main.axml dell'app foto di esempio:
<?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>
Successivamente, il codice viene aggiunto alla fine del metodo dell'attività OnCreate
principale per individuare il Random Pick
pulsante nel layout e allegare un gestore a esso:
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();
}
};
Questo gestore chiama il metodo dell'album RandomSwap
fotografico quando viene toccato il pulsante Selezione casuale. Il RandomSwap
metodo scambia in modo casuale una foto con la prima foto nell'origine dati, quindi restituisce l'indice della foto scambiata in modo casuale. Quando si compila ed esegue l'app di esempio con questo codice, toccando il pulsante Selezione casuale non viene generata una modifica di visualizzazione perché non RecyclerView
è a conoscenza della modifica apportata all'origine dati.
Per mantenere RecyclerView
aggiornato dopo la modifica dell'origine dati, è necessario modificare il gestore clic selezione casuale per chiamare il metodo dell'adattatore NotifyItemChanged
per ogni elemento della raccolta che è stato modificato (in questo caso, due elementi sono stati modificati: la prima foto e la foto scambiata). Ciò comporta RecyclerView
l'aggiornamento della visualizzazione in modo che sia coerente con il nuovo stato dell'origine dati:
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);
}
};
Ora, quando viene toccato il pulsante Selezione casuale, RecyclerView
aggiorna lo schermo per mostrare che una foto più in basso nella raccolta è stata scambiata con la prima foto nella raccolta:
Naturalmente, NotifyDataSetChanged
potrebbe essere stato chiamato invece di effettuare le due chiamate a NotifyItemChanged
, ma in questo modo sarebbe necessario RecyclerView
aggiornare l'intera raccolta anche se solo due elementi nella raccolta erano stati modificati. La chiamata NotifyItemChanged
è notevolmente più efficiente rispetto alla chiamata NotifyDataSetChanged
di .