1. Bienvenue
Ces travaux pratiques se base sur le cours de base pour les développeurs Android fourni par Google afin de les préparer pour le test de certification Associate Android Developer. Vous obtiendrez le plus de valeur de ce TP si vous travaillez successivement dans les codelabs.
Introduction
Réfléchissez un instant aux applications que vous utilisez fréquemment sur votre téléphone. Presque toutes disposent d'au moins une liste. L'écran de l'historique des appels, l'application Contacts et votre application de réseaux sociaux préférée affichent tous une liste de données. Comme le montre la capture d'écran ci-dessous, certaines de ces applications affichent une simple liste de mots ou d'expressions, tandis que d'autres affichent des éléments plus complexes, tels que des fiches contenant du texte et des images. Quel que soit le contenu, l'affichage d'une liste de données est l'une des tâches d'UI les plus courantes dans Android.
Android fournit RecyclerView
pour vous aider à créer des applications avec des listes. RecyclerView garantit une efficacité optimale, même avec de longues listes, grâce à la réutilisation (ou au recyclage) des vues qui ne sont plus affichées à l'écran. Lorsqu'un élément de liste n'est plus affiché à l'écran, RecyclerView
réutilise cette vue pour l'élément suivant qui est sur le point d'être affiché. Cela signifie que l'élément est rempli avec le nouveau contenu qui défile à l'écran. Ce comportement RecyclerView
vous fait gagner beaucoup de temps de traitement et garantit un défilement plus fluide des listes.
Dans la séquence ci-dessous, vous pouvez voir que les données ABC
ont été affichées dans une vue. Une fois que cette vue est sortie de l'écran, RecyclerView
la réutilise pour les nouvelles données, XYZ
.
Dans ce cours pratique, vous ferez ce qui suit :
- Utiliser
RecyclerView
pour afficher une liste défilante. - Ajouter un gestionnaire de clics à chaque élément de la liste.
- Ajouter des éléments à la liste à l'aide d'un bouton d'action flottant (FAB), le bouton rose sur la capture d'écran dans la section Aperçu de l'application. Utilisez un FAB pour l'action principale que vous souhaitez que l'utilisateur effectue.
What you should already know
Vous devriez être familier avec:
- Créer et exécuter des applications dans Android Studio
- Créez et modifiez des éléments d'interface utilisateur à l'aide de l'éditeur de mise en page, en saisissant directement le code XML et en accédant aux éléments à partir de votre code Java.
- Créez et utilisez des ressources de chaîne.
- Convertissez le texte d'une vue en chaîne à l'aide de la méthode getText().
- Ajoutez un gestionnaire
onClick()
à une vue. - Affichez un message
Toast
.
What you'll learn
- Comment utiliser la classe
RecyclerView
pour afficher des éléments dans une liste défilante. - Comment ajouter dynamiquement des éléments au
RecyclerView
lorsqu'ils deviennent visibles grâce au défilement. - Comment effectuer une action lorsque l'utilisateur tape sur un élément spécifique.
- Comment afficher un FAB et effectuer une action lorsque l'utilisateur tape dessus.
What you'll do
- Créez une nouvelle application qui utilise un
RecyclerView
pour afficher une liste d'éléments sous forme de liste déroulante et associer un comportement de clic aux éléments de la liste. - Utilisez un FAB (Floating Action Button) pour permettre à l'utilisateur d'ajouter des éléments au
RecyclerView
.
2. Aperçu de l'application
L'application RecyclerView
démontre comment utiliser un RecyclerView pour afficher une longue liste de mots défilent. Vous créez le jeu de données (les mots), le RecyclerView
lui-même et les actions que l'utilisateur peut effectuer :
- Toucher un mot le marque comme cliqué.
- Toucher le bouton d'action flottant (FAB) ajoute un nouveau mot.
3. Créer un nouveau projet et un nouvel ensemble de données
Avant de pouvoir afficher un RecyclerView
, vous avez besoin de données à afficher. Dans cette tâche, vous allez créer un nouveau projet pour l'application et un ensemble de données. Dans une application plus sophistiquée, vos données peuvent provenir du stockage interne (un fichier, une base de données SQLite, des préférences enregistrées), d'une autre application (Contacts, Photos) ou d'Internet (stockage en nuage, Google Sheets ou toute source de données avec une API). Le stockage et la récupération de données sont un sujet à part entière qui est abordé dans le chapitre sur le stockage de données. Pour cet exercice, vous allez simuler des données en les créant dans la méthode onCreate()
de MainActivity
.
1.1. Créer le projet et la mise en page
- Créez un nouveau projet avec le nom RecyclerView, sélectionnez le modèle "Basic Views Activity".
- Ouvrez
themes.xml
et changez le parent de du thème de l'application par Theme.Material3.Light.NoActionBar et supprimez le fichier themes.xml (night).
C'est juste pour avoir la même interface utilisateur, parce que le mode sombre peut être activé sur vos émulateurs ou téléphones.
<style name="Base.Theme.RecyclerView" parent="Theme.Material3.Light.NoActionBar">
Le modèle Basic Views Activity fournit un bouton d'action flottant (FAB) et une barre d'application dans la mise en page de l'activité (activity_main.xml
), ainsi qu'une mise en page pour le contenu de l'activité (content_main.xml
).
- Supprimez le répertoire "navigation" sous les ressources (
res
). - Supprimez toutes les mises en page et classes Java des fragments.
FirstFragment.java
,SecondFragment.java
,fragment_first.xml
etfragment_second.xml
. - Supprimez la balise
fragment
de "content_main.xml
" et la remplacez par unTextView
qui contient "Hello World". - Supprimez les dépendances de la bibliothèque de navigation et synchronisez le projet.
implementation libs.navigation.fragment
implementation libs.navigation.ui
- Une fois la synchronisation du projet est terminé, nettoyez "
MainActivity.java
" (les imports, methode de navigationonSupportNavigateUp()
et tous les variables en rouge en relation avec la bibliothèque de navigation...) - Exécutez votre application. Vous devriez voir le titre de l'application
RecyclerView
et "Hello World" à l'écran.
1.2. Créer des données
L'étape suivante du processus de création de l'application RecyclerView
consiste à ajouter des ressources. Vous allez ajouter les éléments suivants à votre projet.
- Des mots à afficher dans l'application.
- Une source de données pour fournir une liste des mots à votre application.
Dans l'application RecyclerView, en plus d'importer les classes Android et Java, vous allez organiser votre application dans plusieurs packages. Même si votre application ne contient pas beaucoup de classes, il est recommandé d'utiliser des packages pour les regrouper par fonctionnalité.
1.2.1. Créer un package "model"
- Dans le volet Projet d'Android Studio, effectuez un clic droit sur app > java > com.example.recyclerview, puis sélectionnez New > Package.
- Dans le pop-up New package, notez le préfixe du nom de package suggéré. La première partie est le nom du package sur lequel vous avez effectué un clic droit. Bien que les noms de package ne créent pas de hiérarchie de packages, des parties du nom sont réutilisées pour indiquer une relation et une organisation du contenu.
- Dans le pop-up, ajoutez model à la fin du nom de package suggéré. Les développeurs utilisent souvent model comme nom de package pour les classes qui modélisent (ou représentent) les données.
- Appuyez sur Entrée. Un package est créé sous le package com.example.recyclerview (racine). Ce nouveau package contiendra toutes les classes liées aux données définies dans votre application.
1.2.2. Créer la classe de données "Word"
Dans cette tâche, vous allez créer une classe appelée Word. Une instance d'objet de Word représente un mot et contient "word"avec le mot en question.
- Effectuez un clic droit sur le package com.example.recyclerview.model, puis sélectionnez New > Java Class.
- Dans le pop-up, sélectionnez Class, puis saisissez Word comme nom de classe. Cette opération crée un fichier nommé Word.java dans le package model.
- Pour créer un mot on a besoin juste d'un constructeur pour initialiser le mot dans la classe
Word
et une méthode qui retourne le mot pour l'affichage (getter) si l'attribut word est privé.
Word.java
package com.example.recyclerview.model;
public class Word {
private String mWord;
public Word(String word){
this.mWord = word;
}
public void setWord(String word) {
this.mWord = word;
}
public String getWord() {
return mWord;
}
}
1.2.3. Créer une classe en tant que source de données
Les données affichées dans votre application peuvent provenir de différentes sources (par exemple, de votre projet d'application ou d'une source externe qui nécessite une connexion à Internet pour télécharger des données). Par conséquent, il se peut que les données ne soient pas exactement au format dont vous avez besoin. Le reste de l'application ne doit pas se préoccuper de la provenance ni du format d'origine des données. Vous pouvez (et c'est même conseillé) dissimuler cette préparation de données dans une classe Datasource distincte qui prépare les données pour l'application.
La préparation des données étant un problème distinct, placez la classe Datasource dans un package data séparé.
- Dans la fenêtre Projet d'Android Studio, effectuez un clic droit sur app > java > com.example.recyclerview, puis sélectionnez New > Package.
- Saisissez data comme dernière partie du nom du package.
- Effectuez un clic droit sur le package
data
, puis sélectionnez New > Java Class. - Saisissez DataSource comme nom de classe.
- Initializer un constructeur vide pour Datasource.
public DataSource(){}
- Dans la classe
DataSource
, créez une fonction appeléeloadWords()
.
La fonction loadWords()
doit renvoyer une liste de mots. Pour ce faire, créez une liste et insérez-y une instance Word pour chaque mot.
- Déclarez
LinkedList
comme type renvoyé de la méthodeloadWords()
. - Dans le corps de
loadWords()
, ajoutez ce code pour générer 20 mots.
// Mettre les données initiales dans la liste de mots.
LinkedList<Word> wordList = new LinkedList<>();
for (int i = 0; i < 20; i++) {
wordList.addLast(new Word("Word " + i));
}
return wordList;
Le code concatène la chaîne "Word "
avec la valeur de i
tout en augmentant sa valeur. C'est tout ce dont vous avez besoin comme ensemble de données pour cet exercice.
DataSource.java
package com.example.recyclerview.data;
import com.example.recyclerview.model.Word;
import java.util.LinkedList;
public class DataSource {
public DataSource(){}
public LinkedList<Word> loadWords(){
// Mettre les données initiales dans la liste de mots.
LinkedList<Word> wordList = new LinkedList<>();
for (int i = 0; i < 20; i++) {
wordList.addLast(new Word("Word " + i));
}
return wordList;
}
}
1.3. Modifier l'icône FAB
Pour cette pratique, vous utiliserez un FAB pour générer un nouveau mot à insérer dans la liste. Le modèle d'activité de base fournit un FAB, mais vous pouvez modifier son icône. Comme vous l'avez appris dans une autre leçon, vous pouvez choisir une icône parmi l'ensemble d'icônes d'Android Studio pour le FAB. Suivez ces étapes :
- Développez res dans le volet Project > Android, puis cliquez avec le bouton droit (ou Ctrl-clic) sur le dossier drawable.
- Choisissez New > Image Asset. La boîte de dialogue Image Asset s'affiche.
- Choisissez Action Bar and Tab Items dans le menu déroulant en haut de la boîte de dialogue.
- Changez ic_action_name dans le champ Name par ic_add_for_fab.
- Cliquez sur l'image clipart (le logo Android à côté de Clipart) pour sélectionner une image clipart comme icône. Une page d'icônes apparaît. Cliquez sur l'icône que vous souhaitez utiliser pour le FAB, comme le signe plus (+).
- Choisissez HOLO_LIGHT dans le menu déroulant Theme. Cela définit l'icône pour qu'elle soit blanche sur un fond de couleur sombre (ou noir). Cliquez sur Next.
- Cliquez sur Finish dans la boîte de dialogue Confirmer le chemin de l'icône.
- Ouvrez
activity_main.xml
et remplacez l'icône du bouton flottant.
app:srcCompat="@drawable/ic_add_for_fab"
4. Ajouter une RecyclerView à votre application
La création et l'utilisation d'une RecyclerView reposent sur un certain nombre d'éléments. On peut les considérer comme une division du travail. Le schéma ci-dessous vous donne une vue d'ensemble. Vous en apprendrez davantage sur chaque élément au fur et à mesure de l'implémentation.
- item (élément) : élément de données de la liste à afficher. Représente un objet Word de votre application.
- Adapter (Adaptateur) : accepte les données et les prépare pour que
RecyclerView
les affiche. - ViewHolders : pool de vues que RecyclerView peut utiliser et réutiliser pour afficher des mots.
- RecyclerView : vues affichées à l'écran.
Dans ce TP, vous allez afficher des données dans un RecyclerView
. Vous avez besoin des éléments suivants :
- Données à afficher : Utilisez le
Datasource
- Un
RecyclerView
pour la liste défilante qui contient les éléments de la liste. - Layout for one item of data. All list items look the same.
- Un gestionnaire de mise en page.
RecyclerView.LayoutManager
gère la hiérarchie et la mise en page des éléments View.RecyclerView
nécessite un gestionnaire de mise en page explicite pour gérer l'organisation des éléments de liste contenus en son sein. Cette mise en page peut être verticale, horizontale ou sous forme de grille. Vous utiliserez unLinearLayoutManager
vertical. - Un adaptateur.
RecyclerView.Adapter
connecte vos données auRecyclerView
. Il prépare les données dans unRecyclerView.ViewHolder
. Vous créerez un adaptateur qui insère et met à jour vos mots générés dans vos vues. - Un
ViewHolder
. Dans votre adaptateur, vous créerez unViewHolder
qui contient les informations de vue pour afficher un élément de la disposition de l'élément.
Le diagramme ci-dessous montre la relation entre les données, l'adaptateur, le ViewHolder
et le gestionnaire de mise en page dans notre application.
Pour mettre en œuvre ces pièces, vous devrez :
- Ajoutez un élément
RecyclerView
à la mise en page du contenu XML deMainActivity
(content_main.xml
) pour l'application RecyclerView. - Créez un fichier de mise en page XML (
wordlist_item.xml
) pour un élément de liste, qui estWordListItem
. - Créez un adaptateur (
WordListAdapter
) avec unViewHolder
(WordViewHolder
). - Implémentez la méthode qui prend les données, les place dans le
ViewHolder
et indique au gestionnaire de mise en page qu'il doit les afficher. - Dans la méthode
onCreate()
de MainActivity, créez un RecyclerView et initialisez-le avec l'adaptateur.
Faisons-les une par une ⬇️
2.1. Modifiez la mise en page dans content_main.xml
To add a RecyclerView
element to the XML layout, follow these steps:
- Ouvrez
content_main.xml
dans votre applicationRecyclerView
. Il affiche unTextView
"Hello World
" que nous avons ajouté précédemment en remplacement du fragment. Supprimez leTextView
car nous allons le remplacer par unRecyclerView
. - Dans la Palette, sélectionnez Conteneurs, puis recherchez
RecyclerView
. - Faites glisser une vue
RecyclerView
dans la mise en page. - Si le pop-up "Ajouter une dépendance de projet" s'affiche, lisez-le, puis cliquez sur OK. (Si le pop-up ne s'affiche pas, aucune action n'est requise.)
- Si nécessaire, remplacez les attributs layout_width et layout_height de la RecyclerView par
match_constraint
pour que laRecyclerView
puisse remplir l'intégralité de l'écran. - Définissez l'
ID
de ressource deRecyclerView
surrecyclerview
. - Revenez à la vue Code. Dans l'élément
RecyclerView
du code XML, ajoutezLinearLayoutManager
en tant qu'attribut de gestionnaire de mise en page de laRecyclerView
, comme indiqué ci-dessous.
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
Pour qu'il soit possible de faire défiler une liste verticale d'éléments plus longue que l'écran, vous devez ajouter une barre de défilement verticale.
- Dans
RecyclerView
, ajoutez un attributandroid:scrollbars
défini sur vertical.
android:scrollbars="vertical"
La mise en page XML finale doit ressembler à ceci :
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerview"
android:layout_width="0dp"
android:layout_height="0dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
android:scrollbars="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
- Exécutez votre application.
2.2. Créer la mise en page d'un élément de liste
L'adaptateur a besoin de la mise en page d'un élément de la liste. Tous les éléments utilisent la même mise en page. Vous devez spécifier cette mise en page dans un fichier de ressources de mise en page distinct, car elle est utilisée par l'adaptateur, séparément du RecyclerView
.
Créez une mise en page d'élément de mot simple à l'aide d'une disposition LinearLayout
verticale avec un TextView
.
- Cliquez avec le bouton droit sur le dossier app > res > layout et choisissez New > Layout resource file.
- Nommez le fichier wordlist_item et mettez LinearLayout comme "Root element".
- les attributs de
LinearLayout
est comme suit:
Attribut (LinearLayout) | Valeur |
android:layout_width | "match_parent" |
android:layout_height | "wrap_content" |
android:orientation | "vertical" |
android:padding | "6dp" |
- Ajoutez un
TextView
pour l'affichage du mot auLinearLayout
. Utilisezword_title
comme identifiant duTextView
:
Attribut | Valeur |
android:id | "@+id/word_title" |
android:layout_width | "match_parent" |
android:layout_height | "wrap_content" |
android:textSize | "24sp" |
android:textStyle | "bold" |
2.3 Créer un style à partir des attributs TextView
Vous pouvez utiliser des styles pour permettre aux éléments de partager des groupes d'attributs d'affichage. Un moyen facile de créer un style est d'extraire le style d'un élément d'interface utilisateur que vous avez déjà créé. Pour extraire les informations de style du TextView
de word
dans wordlist_item.xml
:
- Ouvrez le fichier
wordlist_item.xml
s'il n'est pas déjà ouvert. - Cliquez avec le bouton droit sur le
TextView
que vous venez de créer danswordlist_item.xml
et sélectionnez Refactor > Style. La boîte de dialogueExtract Android Style
apparaît. - Nommez votre style
word_title
et laissez toutes les autres options sélectionnées. Sélectionnez l'option "Launch Use Style Where Possible'" et cliquez sur OK. - Lorsque vous êtes invité, appliquez le style à l'ensemble du projet "Whole Project".
- Trouvez et examinez le style
word_title
dans values > styles.xml. - Réouvrez
wordlist_item.xml
s'il n'est pas déjà ouvert. LeTextView
utilise désormais le style à la place des propriétés de style individuelles, comme indiqué ci-dessous.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="6dp">
<TextView
android:id="@+id/word_title"
style="@style/word_title" />
</LinearLayout>
2.4. Créer un adaptateur
Android utilise des adaptateurs (à partir de la classe Adapter
) pour connecter les données aux éléments de vue (View) d'une liste. Il existe de nombreux types d'adaptateurs différents, et vous pouvez également écrire des adaptateurs personnalisés. Dans cette tâche, vous allez créer un adaptateur qui associe votre liste de mots aux éléments de vue (View) de la liste de mots.
Pour connecter les données aux éléments de la vue, l'adaptateur doit connaître les éléments de la vue. L'adaptateur utilise un ViewHolder
qui décrit un élément de la vue et sa position dans le RecyclerView
.
Tout d'abord, vous allez créer un adaptateur qui fera le pont entre les données de votre liste de mots et le RecyclerView
qui l'affiche.
- Effectuez un clic droit sur app > java > com.example.recyclerview, puis sélectionnez New > Package.
- Saisissez adapter comme dernière partie du nom du package.
- Effectuez un clic droit sur le package adapter, puis sélectionnez New > Java Class.
- Saisissez WordListAdapter comme nom de classe.
- donner à WordListAdapter la signature suivante (n'oubliez pas d'importer les classes nécessaire):
public class WordListAdapter extends
RecyclerView.Adapter<WordListAdapter.WordViewHolder> {}
WordListAdapter
hérite d'un adaptateur générique pour RecyclerView
afin d'utiliser un ViewHolder
spécifique à votre application et défini à l'intérieur de WordListAdapter
. WordViewHolder
affiche une erreur car vous ne l'avez pas encore défini.
- Cliquez sur la déclaration de classe (WordListAdapter), puis cliquez sur l'ampoule rouge sur le côté gauche du volet (ou Alt+Entrée). Choisissez Implement methods.
- Une boîte de dialogue apparaît et vous demande de choisir les méthodes à implémenter. Choisissez les trois méthodes et cliquez sur OK.
Android Studio crée des placeholders vides pour toutes les méthodes. Notez comment onCreateViewHolder
et onBindViewHolder
font toutes deux référence à WordViewHolder
, qui n'a pas encore été implémentée.
2.5 Créer le ViewHolder pour l'adaptateur
Pour créer le ViewHolder
, suivez ces étapes
- À l'intérieur de la classe
WordListAdapter
, ajoutez une nouvelle sous-classeWordViewHolder
avec la signature suivante :
public class WordViewHolder extends RecyclerView.ViewHolder {
}
Vous verrez une erreur concernant un constructeur par défaut manquant. Vous pouvez voir les détails des erreurs en passant votre souris sur le code souligné en rouge ou sur toute ligne horizontale rouge dans la marge droite de la zone d'édition.
- Ajoutez des variables à la sous-classe
WordViewHolder
pour leTextView
et l'adaptateur:
public final TextView wordItemView;
final WordListAdapter mAdapter;
- Dans la sous-classe
WordViewHolder
, ajoutez un constructeur qui initialise leViewHolder
,TextView
à partir de la ressource XMLword_title
et définit son adaptateur.
public WordViewHolder(View itemView, WordListAdapter adapter) {
super(itemView);
wordItemView = itemView.findViewById(R.id.word_title);
this.mAdapter = adapter;
}
- Exécutez votre application pour vous assurer qu'il n'y a pas d'erreurs. Vous ne verrez toujours qu'une vue vide.
- Cliquez sur l'onglet
Logcat
pour afficher le voletLogcat
, et notez l'avertissementE/RecyclerView: No adapter attached; skipping layout
. Vous attacherez l'adaptateur auRecyclerView
dans une autre étape.
2.6 Stocker vos données dans l'adaptateur
Vous devez stocker vos données dans l'adaptateur, et WordListAdapter
doit avoir un constructeur qui initialise la liste de mots à partir des données. Suivez ces étapes :
- Pour stocker vos données dans l'adaptateur, créez une liste chaînée privée de
Word
dansWordListAdapter
et appelez-lamWordList
.
private final LinkedList<Word> mWordList;
- Implémentez le constructeur pour
WordListAdapter
. Le constructeur doit avoir une liste chaînée de mots avec les données de l'application. La méthode doit définirmWordList
sur les données passées en entrée.
public WordListAdapter(LinkedList<Word> mWordList) {
this.mWordList = mWordList;
}
- Vous pouvez maintenant remplir la méthode
getItemCount()
pour renvoyer la taille demWordList
.
La méthode getItemCount() doit renvoyer la taille de votre ensemble de données. Les données de votre application se trouvent dans la propriété mWordList que vous transmettez au constructeur WordListAdapter. Vous pouvez obtenir leur taille avec size:
@Override
public int getItemCount() {
return mWordList.size();
}
- La méthode
onCreateViewHolder()
est appelée par le gestionnaire de mises en page afin de créer des conteneurs de vues pour laRecyclerView
(s'il n'existe aucun conteneur de vues pouvant être réutilisé). N'oubliez pas qu'un conteneur de vues représente une seule vue d'élément de liste.
Dans la méthodeonCreateViewHolder()
, vous devez obtenir une instance deLayoutInflater
à partir du contexte fourni (context
duparent
). Le système de gonflage de mise en page sait comment gonfler une mise en page XML dans une hiérarchie d'objets de vue.
Une fois que vous disposez d'une instance d'objet LayoutInflater, ajoutez un point suivi d'un autre appel de méthode pour gonfler la vue d'élément de liste. Transmettez l'ID
de ressource de mise en page XMLR.layout.wordlist_item
et le groupe de vuesparent
. Le troisième argument booléen estattachToRoot
. Cet argument doit êtrefalse
, carRecyclerView
ajoute automatiquement cet élément à la hiérarchie des vues le moment venu.
Remplissez la méthodeonCreateViewHolder()
avec ce code:
@NonNull
@Override
public WordListAdapter.WordViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View adapterLayout = LayoutInflater.from(parent.getContext())
.inflate(R.layout.wordlist_item, parent, false);
return new WordViewHolder(adapterLayout, this);
}
- La dernière méthode que vous devez remplacer est
onBindViewHolder()
. Cette méthode est appelée par le gestionnaire de mise en page afin de remplacer le contenu d'une vue d'élément de liste.
La méthodeonBindViewHolder()
comporte deux paramètres : unWordViewHolder
créé précédemment par la méthodeonCreateViewHolder()
et unint
représentant la position actuelle de l'élément dans la liste. Cette méthode vous permet de trouver l'objet Word approprié dans l'ensemble de données en fonction de la position.
Vous devez mettre à jour toutes les vues référencées par le conteneur de vues afin de tenir compte des données correctes pour cet élément. Dans le cas présent, il n'y a qu'une seule vue :TextView
dansWordViewHolder
. Définissez le texte deTextView
pour afficher la chaîneWord
de cet élément.
Remplissez la méthodeonBindViewHolder()
avec le code suivant :
@Override
public void onBindViewHolder(@NonNull WordListAdapter.WordViewHolder holder, int position) {
Word mCurrent = mWordList.get(position);
holder.wordItemView.setText(mCurrent.getWord());
}
Voici le code d'adaptateur terminé.
public class WordListAdapter extends RecyclerView.Adapter<WordListAdapter.WordViewHolder>
{
private final LinkedList<Word> mWordList;
public WordListAdapter(LinkedList<Word> mWordList) {
this.mWordList = mWordList;
}
/**
* Créer de nouvelles vues
* (appelé par le gestionnaire de disposition "LayoutManager")
*/
@NonNull
@Override
public WordListAdapter.WordViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
// créer une nouvelle vue
View adapterLayout = LayoutInflater.from(parent.getContext())
.inflate(R.layout.wordlist_item, parent, false);
return new WordViewHolder(adapterLayout, this);
}
/**
* Remplacer le contenu d'une vue
* (appelé par le gestionnaire de disposition "LayoutManager")
*/
@Override
public void onBindViewHolder(@NonNull WordListAdapter.WordViewHolder holder, int position) {
Word mCurrent = mWordList.get(position);
holder.wordItemView.setText(mCurrent.getWord());
}
/**
* Renvoyer la taille de votre ensemble de données
* (appelé par le gestionnaire de disposition "LayoutManager")
*/
@Override
public int getItemCount() {
return mWordList.size();
}
public class WordViewHolder extends RecyclerView.ViewHolder {
public final TextView wordItemView;
final WordListAdapter mAdapter;
public WordViewHolder(View itemView, WordListAdapter adapter) {
super(itemView);
wordItemView = itemView.findViewById(R.id.word_title);
this.mAdapter = adapter;
}
}
}
- Exécutez votre application pour vous assurer qu'il n'y a pas d'erreurs.
2.7. Créer RecyclerView dans l'activité principale.
Pour terminer, vous devez utiliser vos classes Datasource
et WordListAdapter
pour créer et afficher des éléments dans RecyclerView
. Cette opération est effectuée dans MainActivity
.
Maintenant que vous avez un adaptateur avec un ViewHolder
, vous pouvez enfin créer un RecyclerView
et connecter toutes les pièces pour afficher vos données.
- Ouvrez
MainActivity
. - Dans
MainActivity
, accédez à la méthodeonCreate()
. Insérez le nouveau code décrit dans les étapes suivantes après l'appel verssetContentView(binding.getRoot())
. - Créez une instance de
Datasource
sous le nommDataSource
DataSource mDataSource = new DataSource();
- Appelez la méthode
loadWords()
sur l'instancemDatasource
. Stockez la liste des mots renvoyée dans un variable local nommémWordList
.
// Charger la liste des mots
LinkedList<Word> mWordList = mDataSource.loadWords();
- Ajouter une variable membre de la classe
MainActivity
pour l'adaptateur. Par contre pour leRecyclerView
, nous utiliserons la bibliothèque de liaison de vues (View Binding), utilisée par le nouveau modèle d'activité de vue de base, au lieu de la méthodefindViewById()
:
private WordListAdapter mAdapter;
Pour vérifier que la liaison de vue (View Binding) est activée dans un module, accédez au fichier build.gradle
au niveau du module et vérifiez que viewBinding
est défini sur true comme le montre l'exemple suivant :
android {
...
buildFeatures {
viewBinding true
}
}
- Notre
RecyclerView
est défini danscontent_main.xml
et nous utilisonsinclude
dansactivity_main.xml
pour l'inclure. Comme il s'agit d'une mise en page imbriquée (une mise en page à l'intérieur d'une autre mise en page), la fonctionnalitéView Binding
ne peut pas voir les vues à l'intérieur decontent_main.xml
. Pour les exposer, il suffit d'ajouter unID
à la baliseinclude
dansactivity_main.xml
Allez dansactivity_main.xml
et localisez la baliseinclude
, puis ajoutez-luicontent_main
comme unID
:
<include layout="@layout/content_main" android:id="@+id/content_main" />
- Revenez à la méthode
onCreate()
deMainActivity
, ajoutez le code suivant qui connecte leRecyclerView
avec l'adaptateur et les données. Les commentaires expliquent chaque ligne. Vous devez insérer ce code après l'initialisation demWordList
.
// Créer une instance de l'adaptateur en passant la liste des mots comme paramètre
mAdapter = new WordListAdapter(mWordList);
// Lier RecyclerView à son adaptateur
// binding.contentMain.recyclerview remplace findViewById(R.id.recyclerview)
binding.contentMain.recyclerview.setAdapter(mAdapter);
- Étant donné que la taille de mise en page de votre
RecyclerView
est fixe dans la mise en page de l'activité, vous pouvez définir le paramètresetHasFixedSize
deRecyclerView
sur true. Ce paramètre ne sert qu'à améliorer les performances. Utilisez ce paramètre si vous savez que les modifications apportées au contenu n'ont pas d'incidence sur la taille de mise en page deRecyclerView
.
binding.contentMain.recyclerview.setHasFixedSize(true)
- Exécutez votre application.
Vous devriez voir votre liste de mots affichée, et vous pouvez faire défiler la liste.
Félicitations ! Vous venez de créer une application qui affiche une liste de données avec RecyclerView
et un adaptateur personnalisé. Prenez le temps d'examiner le code que vous avez créé et de comprendre l'interaction entre les différents éléments.
5. Rendre la liste interactive
Regarder des listes d'éléments est intéressant, mais c'est beaucoup plus amusant et utile si votre utilisateur peut interagir avec elles. Pour voir comment le RecyclerView
peut répondre à la saisie de l'utilisateur, vous allez attacher un gestionnaire de clic à chaque élément. Lorsque l'élément est tapé, le gestionnaire de clic est exécuté et le texte de cet élément change.
La liste d'éléments qu'un RecyclerView
affiche peut également être modifiée dynamiquement, elle n'a pas besoin d'être une liste statique. Il existe plusieurs façons d'ajouter des comportements supplémentaires. L'une d'entre elles consiste à utiliser le bouton d'action flottant (FAB). Par exemple, dans Gmail, le FAB est utilisé pour composer un nouvel e-mail. Pour ce pratique, vous allez générer un nouveau mot à insérer dans la liste. Pour une application plus utile, vous obtiendriez des données de vos utilisateurs.
3.1. Faire réagir les éléments aux clics
- Ouvrez
WordListAdapter
. - Modifiez la signature de la classe
WordViewHolder
pour implémenter View.onClickListener:
class WordViewHolder extends RecyclerView.ViewHolder
implements View.OnClickListener {
- Cliquez sur l'en-tête de la classe et sur l'ampoule rouge pour implémenter des stubs pour les méthodes requises, qui dans ce cas est juste la méthode
onClick()
. - Ajoutez le code suivant au corps de la méthode
onClick()
:
// Obtenez la position de l'élément cliqué
int mPosition = getLayoutPosition();
// Utilisez cela pour accéder à l'élément affecté dans mWordList.
Word element = mWordList.get(mPosition);
// Modifiez le mot dans la liste mWordList.
element.setWord("Clicked! " + element.getWord());
mWordList.set(mPosition, element);
// Notifier l'adaptateur que les données ont changé afin qu'il
// puisse mettre à jour le RecyclerView pour afficher les données
mAdapter.notifyDataSetChanged();
- Connectez l'
onClickListener
à la vue. Ajoutez ce code au constructeurWordViewHolder
(sous la lignethis.mAdapter = adapter
):
itemView.setOnClickListener(this);
- Lancez votre application. Cliquez sur les éléments pour voir le texte changer
3.2. Ajouter plus de données (un nouveau mot)
Dans cette tâche, vous allez implémenter une action pour le FAB afin de :
- Ajouter un mot à la fin de la liste de mots.
- Notifier l'adaptateur que les données ont changé.
- Faire défiler jusqu'à l'élément inséré..
Suivez ces étapes:
- Ouvrir
MainActivity
. La méthodeonCreate()
définit unOnClickListener()
sur leFloatingActionButton
avec une méthodeonClick()
pour effectuer une action. Modifiez la méthodeonClick()
comme suit :
@Override
public void onClick(View view) {
int wordListSize = mWordList.size();
// Ajoutez un nouveau mot à la liste de mots.
mWordList.addLast(new Word("+ Word " + wordListSize));
// Notifiez l'adaptateur qu'une nouvelle donnée a été insérée.
binding.contentMain.recyclerview.getAdapter().notifyItemInserted(wordListSize);
// Faites défiler jusqu'en bas
binding.contentMain.recyclerview.smoothScrollToPosition(wordListSize);
}
- Exécuter l'application.
- Faites défiler la liste de mots et cliquez sur les éléments.
- Ajouter des éléments en cliquant sur le FAB.
6. Résumé
- RecyclerView est un moyen efficace d'afficher une liste d'éléments défilante.
- Pour créer une vue pour chaque élément de liste, l'adaptateur gonfle une ressource de mise en page XML pour un élément de liste à l'aide de
LayoutInflator
. LinearLayoutManager
est un gestionnaire de mise en pageRecyclerView
qui affiche les éléments dans une liste à défilement vertical ou horizontal.GridLayoutManager
est un gestionnaire de dispositionRecyclerView
qui affiche les éléments dans une grille.StaggeredGridLayoutManager
est un gestionnaire de dispositionRecyclerView
qui affiche les éléments dans une grille décalée.- Utilisez
RecyclerView.Adapter
pour connecter vos données auRecyclerView
. Il prépare les données dans unRecyclerView.ViewHolder
qui décrit un élémentView
et sa position dans leRecyclerView
. - Implémenter
View.onClickListener
pour détecter les clics de souris dans un RecyclerView.
7. Apprendre encore plus
Android Studio documentation:
Android developer documentation:
RecyclerView
LayoutInflator
RecyclerView.LayoutManager
LinearLayoutManager
GridLayoutManager
StaggeredGridLayoutManager
CoordinatorLayout
ConstraintLayout
RecyclerView.Adapter
RecyclerView.ViewHolder
View.onClickListener
- Create a list with
RecyclerView
Video:
8. Travail à faire (Compte Rendu)
Créer et exécuter une application
Créer une application qui utilise un RecyclerView
pour afficher une liste de recettes. Chaque élément de la liste doit indiquer le nom de la recette avec une courte description. Lorsque l'utilisateur appuie sur une recette (un élément de la liste), démarrer une activité (Activity
) qui affiche le texte complet de la recette.
- Utiliser des éléments et un style
TextView
distincts pour le nom et la description de la recette. - Il est possible d'utiliser un texte d'espace réservé (placeholder) pour les recettes complètes.
- En option, ajouter une image du plat fini à chaque recette.
- Cliquer sur le bouton Haut ramène l'utilisateur à la liste des recettes.
La capture d'écran ci-dessous montre un exemple d'implémentation simple. L'application peut avoir un aspect très différent, tant qu'elle dispose des fonctionnalités requises.
Répondre à ces questions
Question 1
Laquelle des affirmations suivantes concernant une RecyclerView
est fausse ? Choisissez-en un.
- Un
RecyclerView
est un moyen plus économe en ressources pour afficher des listes déroulantes. - Il faut fournir une mise en page (layout) pour un seul élément de la liste.
- Tous les éléments de la liste se ressemblent.
- on a pas besoin d'un gestionnaire de disposition (layout manager) avec un
RecyclerView
pour gérer la hiérarchie et la disposition des élémentsView
.
Question 2
Lequel des éléments suivants est le composant principal dont vous avez besoin pour fournir à un adaptateur un élément de vue et sa position dans un RecyclerView
?Choisissez-en un.
RecyclerView
RecyclerView.Adapter
RecyclerView.ViewHolder
AppCompatActivity
Question 3
Quelle interface doit-on implémenter pour écouter et répondre aux clics des utilisateurs dans une RecyclerView
? Choisissez-en un.
View.onClickListener
RecyclerView.Adapter
RecyclerView.ViewHolder
View.OnKeyListener
Soumettez votre application pour la notation
Vérifier que l'application dispose des fonctionnalités suivantes :
- Implémente un
RecyclerView
qui affiche une liste déroulante de titres de recettes et de courtes descriptions. - Le code étend ou implémente
RecyclerView
,RecyclerView.Adapter
,RecyclerView.ViewHolder
etView.OnClickListener
. - Cliquer sur un élément de la liste démarre une activité (
Activity
) qui affiche la recette complète. - Le fichier
AndroidManifest.xml
définit une relation parent de sorte que cliquer sur le bouton Haut dans une vue de recette revient à la liste des recettes. - ViewHolder contient une mise en page avec deux éléments
TextView
; par exemple, unLinearLayout
avec deux élémentsTextView
.