Extension de l’exemple RecyclerView
L’application de base décrite dans A Basic RecyclerView Example ne fait pas grand-chose , il fait simplement défiler et affiche une liste fixe d’éléments de photographie pour faciliter la navigation. Dans les applications réelles, les utilisateurs s’attendent à pouvoir interagir avec l’application en appuyant sur des éléments dans l’affichage. En outre, la source de données sous-jacente peut changer (ou être modifiée par l’application), et le contenu de l’affichage doit rester cohérent avec ces modifications. Dans les sections suivantes, vous allez apprendre à gérer les événements de clic d’élément et à mettre à jour RecyclerView
lorsque la source de données sous-jacente change.
Gestion des événements Item-Click
Lorsqu’un utilisateur touche un élément dans le RecyclerView
, un événement item-click est généré pour notifier l’application à quel élément a été touché. Cet événement n’est pas généré par RecyclerView
: à la place, l’affichage d’élément (qui est encapsulé dans le titulaire de la vue) détecte les touches et signale ces touches en tant qu’événements de clic.
Pour illustrer comment gérer les événements de clic d’élément, les étapes suivantes expliquent comment l’application d’affichage photo de base est modifiée pour signaler la photographie qui a été touchée par l’utilisateur. Lorsqu’un événement item-click se produit dans l’exemple d’application, la séquence suivante se produit :
La photo détecte l’événement item-click et avertit l’adaptateur
CardView
.L’adaptateur transfère l’événement (avec des informations de position d’élément) au gestionnaire de clics d’élément de l’activité.
Le gestionnaire de clics d’élément de l’activité répond à l’événement item-click.
Tout d’abord, un membre de gestionnaire d’événements appelé ItemClick
est ajouté à la définition de PhotoAlbumAdapter
classe :
public event EventHandler<int> ItemClick;
Ensuite, une méthode de gestionnaire d’événements item-click est ajoutée à MainActivity
.
Ce gestionnaire affiche brièvement un toast qui indique quel élément de photographie a été touché :
void OnItemClick (object sender, int position)
{
int photoNum = position + 1;
Toast.MakeText(this, "This is photo number " + photoNum, ToastLength.Short).Show();
}
Ensuite, une ligne de code est nécessaire pour inscrire le OnItemClick
gestionnaire auprès PhotoAlbumAdapter
de . Un bon endroit pour le faire est immédiatement après PhotoAlbumAdapter
la création :
mAdapter = new PhotoAlbumAdapter (mPhotoAlbum);
mAdapter.ItemClick += OnItemClick;
Dans cet exemple de base, l’inscription de gestionnaires a lieu dans la méthode de l’activité principale, mais une application de OnCreate
production peut inscrire le gestionnaire dans OnResume
et l’annuler OnPause
. Pour plus d’informations, consultez cycle de vie de l’activité.
PhotoAlbumAdapter
appellera OnItemClick
maintenant lorsqu’il reçoit un événement item-click. L’étape suivante consiste à créer un gestionnaire dans l’adaptateur qui déclenche cet ItemClick
événement. La méthode suivante est OnClick
ajoutée immédiatement après la méthode de l’adaptateur ItemCount
:
void OnClick (int position)
{
if (ItemClick != null)
ItemClick (this, position);
}
Cette OnClick
méthode est l’écouteur de l’adaptateur pour les événements de clic d’élément à partir d’affichages d’éléments. Avant que cet écouteur puisse être inscrit avec un affichage d’élément (via le titulaire d’affichage de l’affichage de l’élément), le PhotoViewHolder
constructeur doit être modifié pour accepter cette méthode en tant qu’argument supplémentaire et s’inscrire OnClick
auprès de l’événement d’affichage Click
d’élément.
Voici le constructeur modifié 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);
}
Le itemView
paramètre contient une référence à celle CardView
qui a été touchée par l’utilisateur. Notez que la classe de base du titulaire d’affichage connaît la position de disposition de l’élément (CardView
) qu’elle représente (via la LayoutPosition
propriété) et que cette position est passée à la méthode de OnClick
l’adaptateur lorsqu’un événement item-click a lieu. La méthode de l’adaptateur OnCreateViewHolder
est modifiée pour passer la méthode de OnClick
l’adaptateur au constructeur du titulaire d’affichage :
PhotoViewHolder vh = new PhotoViewHolder (itemView, OnClick);
Maintenant, lorsque vous créez et exécutez l’exemple d’application d’affichage de photos, l’appui sur une photo dans l’affichage entraîne l’affichage d’un toast indiquant que la photographie a été touchée :
Cet exemple illustre une seule approche pour l’implémentation de gestionnaires d’événements avec RecyclerView
. Une autre approche qui pourrait être utilisée ici consiste à placer des événements sur le titulaire de la vue et que l’adaptateur s’abonne à ces événements. Si l’exemple d’application photo a fourni une fonctionnalité d’édition de photos, des événements distincts seraient nécessaires pour les ImageView
éléments suivants CardView
TextView
: touches sur la TextView
boîte de dialogue lancerait une EditView
boîte de dialogue qui permet à l’utilisateur de modifier le légende et touche le ImageView
lancement d’un outil tactile photo qui permet à l’utilisateur de rogner ou de faire pivoter la photo. Selon les besoins de votre application, vous devez concevoir la meilleure approche pour gérer et répondre aux événements tactiles.
Pour montrer comment RecyclerView
mettre à jour lorsque le jeu de données change, l’exemple d’application d’affichage de photos peut être modifié de manière aléatoire pour choisir une photo dans la source de données et la permuter avec la première photo. Tout d’abord, un bouton Sélection aléatoire est ajouté à l’exemple de disposition Main.axml de l’application photo :
<?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>
Ensuite, le code est ajouté à la fin de la méthode de l’activité OnCreate
principale pour localiser le Random Pick
bouton dans la disposition et y attacher un gestionnaire :
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();
}
};
Ce gestionnaire appelle la méthode de RandomSwap
l’album photo lorsque le bouton Sélection aléatoire est appuyé. La RandomSwap
méthode échange aléatoirement une photo avec la première photo de la source de données, puis retourne l’index de la photo permutée de façon aléatoire. Lorsque vous compilez et exécutez l’exemple d’application avec ce code, l’appui sur le bouton Sélection aléatoire n’entraîne pas de modification d’affichage, car il RecyclerView
n’est pas conscient de la modification apportée à la source de données.
Pour conserver RecyclerView
la mise à jour après les modifications de la source de données, le gestionnaire de clic sélection aléatoire doit être modifié pour appeler la méthode de NotifyItemChanged
l’adaptateur pour chaque élément de la collection qui a changé (dans ce cas, deux éléments ont changé : la première photo et la photo permutée). Cela entraîne RecyclerView
la mise à jour de son affichage afin qu’il soit cohérent avec le nouvel état de la source de données :
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);
}
};
Maintenant, lorsque le bouton Sélection aléatoire est appuyé, RecyclerView
met à jour l’affichage pour montrer qu’une photo plus bas dans la collection a été échangée avec la première photo de la collection :
Bien sûr, NotifyDataSetChanged
aurait pu être appelé au lieu d’effectuer les deux appels à NotifyItemChanged
, mais cela forcerait RecyclerView
à actualiser l’ensemble de la collection même si seulement deux éléments de la collection avaient changé. L’appel NotifyItemChanged
est beaucoup plus efficace que l’appel NotifyDataSetChanged
.