Créer des listes dynamiques avec RecyclerView Fait partie d'Android Jetpack.

Essayer Compose
Jetpack Compose est le kit d'outils d'interface utilisateur recommandé pour Android. Découvrez comment utiliser les mises en page dans Compose.

RecyclerView facilite l'affichage efficace de grands ensembles de données. Vous fournissez les données et définissez l'apparence de chaque élément, puis la bibliothèque RecyclerView crée les éléments de manière dynamique lorsqu'ils sont nécessaires.

Comme son nom l'indique, RecyclerView recycle ces éléments individuels. Lorsqu'un élément sort de l'écran, RecyclerView ne détruit pas sa vue. À la place, RecyclerView réutilise la vue pour les nouveaux éléments qui ont été défilés à l'écran. RecyclerView améliore les performances et la réactivité de votre application, et réduit la consommation d'énergie.

Classes de clés

Plusieurs classes collaborent pour créer votre liste dynamique.

  • RecyclerView est la ViewGroup contenant les vues correspondant à vos données. Il s'agit d'une vue elle-même. Vous devez donc ajouter RecyclerView à votre mise en page de la même manière que vous ajouteriez tout autre élément d'interface utilisateur.

  • Chaque élément de la liste est défini par un objet conteneur de vues. Lorsque le conteneur de vues est créé, aucune donnée ne lui est associée. Une fois le conteneur de vues créé, RecyclerView l'associe à ses données. Pour définir le conteneur de vues, étendez RecyclerView.ViewHolder.

  • RecyclerView demande des vues et les lie à leurs données en appelant des méthodes dans l'adaptateur. Pour définir l'adaptateur, vous devez étendre RecyclerView.Adapter.

  • Le gestionnaire de mises en page organise les éléments individuels de votre liste. Vous pouvez utiliser l'un des gestionnaires de mise en page fournis par la bibliothèque RecyclerView ou définir le vôtre. Les gestionnaires de mise en page sont tous basés sur la classe abstraite LayoutManager de la bibliothèque.

Vous pouvez voir comment tous les éléments s'assemblent dans l'application exemple RecyclerView (Kotlin) ou l'application exemple RecyclerView (Java).

Étapes d'implémentation de RecyclerView

Si vous souhaitez utiliser RecyclerView, vous devez effectuer certaines opérations, qui sont expliquées en détail dans les sections suivantes.

  1. Déterminez l'apparence de la liste ou de la grille. En règle générale, vous pouvez utiliser l'un des gestionnaires de mise en page standards de la bibliothèque RecyclerView.

  2. Concevez l'apparence et le comportement de chaque élément de la liste. Sur la base de cette conception, étendez la classe ViewHolder. Votre version de ViewHolder fournit toutes les fonctionnalités de vos éléments de liste. Votre conteneur de vue est un wrapper autour d'un View, et cette vue est gérée par RecyclerView.

  3. Définissez la Adapter qui associe vos données aux vues ViewHolder.

Il existe également des options de personnalisation avancées qui vous permettent d'adapter votre RecyclerView à vos besoins exacts.

Planifier la mise en page

Les éléments de votre RecyclerView sont organisés par une classe LayoutManager. La bibliothèque RecyclerView fournit trois gestionnaires de mise en page qui gèrent les situations de mise en page les plus courantes:

  • LinearLayoutManager organise les éléments dans une liste à une seule dimension.
  • GridLayoutManager organise les éléments dans une grille à deux dimensions :
    • Si la grille est disposée verticalement, GridLayoutManager essaie que tous les éléments de chaque ligne aient la même largeur et la même hauteur, mais des lignes différentes peuvent avoir des hauteurs différentes.
    • Si la grille est disposée horizontalement, GridLayoutManager essaie que tous les éléments de chaque colonne aient la même largeur et la même hauteur, mais des colonnes différentes peuvent avoir des largeurs différentes.
  • StaggeredGridLayoutManager est semblable à GridLayoutManager, mais il n'est pas nécessaire que les éléments d'une ligne aient la même hauteur (pour les grilles verticales) ou que les éléments de la même colonne aient la même largeur (pour les grilles horizontales). Par conséquent, les éléments d'une ligne ou d'une colonne peuvent être décalés les uns par rapport aux autres.

Vous devez également concevoir la mise en page de chaque élément. Vous aurez besoin de cette mise en page pour concevoir le conteneur de vues, comme décrit dans la section suivante.

Implémenter l'adaptateur et le conteneur de vue

Une fois que vous avez déterminé votre mise en page, vous devez implémenter votre Adapter et votre ViewHolder. Ces deux classes fonctionnent ensemble pour définir la manière dont vos données sont affichées. ViewHolder est un wrapper autour d'un View qui contient la mise en page d'un élément individuel de la liste. Adapter crée des objets ViewHolder si nécessaire et définit les données de ces vues. Le processus d'association des vues à leurs données est appelé liaison.

Lorsque vous définissez votre adaptateur, vous remplacez trois méthodes de clé:

  • onCreateViewHolder() : RecyclerView appelle cette méthode chaque fois qu'il doit créer un ViewHolder. La méthode crée et initialise ViewHolder et son View associé, mais ne remplit pas le contenu de l'affichage. ViewHolder n'a pas encore été lié à des données spécifiques.

  • onBindViewHolder() : RecyclerView appelle cette méthode pour associer un ViewHolder aux données. La méthode récupère les données appropriées et les utilise pour remplir la mise en page du conteneur de vues. Par exemple, si RecyclerView affiche une liste de noms, la méthode peut trouver le nom approprié dans la liste et remplir le widget TextView du conteneur de vues.

  • getItemCount() : RecyclerView appelle cette méthode pour obtenir la taille de l'ensemble de données. Par exemple, dans une application de carnet d'adresses, il peut s'agir du nombre total d'adresses. RecyclerView l'utilise pour déterminer à quel moment aucun autre élément ne peut être affiché.

Voici un exemple type d'adaptateur simple avec un élément ViewHolder imbriqué qui affiche une liste de données. Dans ce cas, RecyclerView affiche une simple liste d'éléments de texte. L'adaptateur reçoit un tableau de chaînes contenant le texte des éléments ViewHolder.

Kotlin


class CustomAdapter(private val dataSet: Array<String>) :
        RecyclerView.Adapter<CustomAdapter.ViewHolder>() {

    /**
     * Provide a reference to the type of views that you are using
     * (custom ViewHolder)
     */
    class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
        val textView: TextView

        init {
            // Define click listener for the ViewHolder's View
            textView = view.findViewById(R.id.textView)
        }
    }

    // Create new views (invoked by the layout manager)
    override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): ViewHolder {
        // Create a new view, which defines the UI of the list item
        val view = LayoutInflater.from(viewGroup.context)
                .inflate(R.layout.text_row_item, viewGroup, false)

        return ViewHolder(view)
    }

    // Replace the contents of a view (invoked by the layout manager)
    override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) {

        // Get element from your dataset at this position and replace the
        // contents of the view with that element
        viewHolder.textView.text = dataSet[position]
    }

    // Return the size of your dataset (invoked by the layout manager)
    override fun getItemCount() = dataSet.size

}

Java


public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.ViewHolder> {

    private String[] localDataSet;

    /**
     * Provide a reference to the type of views that you are using
     * (custom ViewHolder)
     */
    public static class ViewHolder extends RecyclerView.ViewHolder {
        private final TextView textView;

        public ViewHolder(View view) {
            super(view);
            // Define click listener for the ViewHolder's View

            textView = (TextView) view.findViewById(R.id.textView);
        }

        public TextView getTextView() {
            return textView;
        }
    }

    /**
     * Initialize the dataset of the Adapter
     *
     * @param dataSet String[] containing the data to populate views to be used
     * by RecyclerView
     */
    public CustomAdapter(String[] dataSet) {
        localDataSet = dataSet;
    }

    // Create new views (invoked by the layout manager)
    @Override
    public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
        // Create a new view, which defines the UI of the list item
        View view = LayoutInflater.from(viewGroup.getContext())
                .inflate(R.layout.text_row_item, viewGroup, false);

        return new ViewHolder(view);
    }

    // Replace the contents of a view (invoked by the layout manager)
    @Override
    public void onBindViewHolder(ViewHolder viewHolder, final int position) {

        // Get element from your dataset at this position and replace the
        // contents of the view with that element
        viewHolder.getTextView().setText(localDataSet[position]);
    }

    // Return the size of your dataset (invoked by the layout manager)
    @Override
    public int getItemCount() {
        return localDataSet.length;
    }
}

La mise en page de chaque élément de la vue est définie, comme d'habitude, dans un fichier de mise en page XML. Dans ce cas, l'application dispose d'un fichier text_row_item.xml comme celui-ci:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="@dimen/list_item_height"
    android:layout_marginLeft="@dimen/margin_medium"
    android:layout_marginRight="@dimen/margin_medium"
    android:gravity="center_vertical">

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/element_text"/>
</FrameLayout>

Étapes suivantes

L'extrait de code suivant montre comment utiliser RecyclerView.

Kotlin


class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val dataset = arrayOf("January", "February", "March")
        val customAdapter = CustomAdapter(dataset)

        val recyclerView: RecyclerView = findViewById(R.id.recycler_view)
        recyclerView.adapter = customAdapter

    }

}

Java


RecyclerView recyclerView = findViewById(R.id.recycler_view);
recyclerView.setAdapter(customAdapter);

La bibliothèque offre également de nombreuses façons de personnaliser votre implémentation. Pour en savoir plus, consultez la section Personnalisation avancée de RecyclerView.

Ressources supplémentaires

Pour en savoir plus sur les tests sur Android, consultez les ressources suivantes.

Exemples d'applications