Migrer RecyclerView vers une liste différée

RecyclerView est un composant View qui permet d'afficher efficacement de grands ensembles de données. Au lieu de créer des vues pour chaque élément de l'ensemble de données, RecyclerView améliore les performances de votre application en conservant un petit pool de vues et en les recyclant lorsque vous faites défiler ces éléments.

Dans Compose, vous pouvez utiliser des listes différées pour obtenir le même résultat. Cette page explique comment migrer votre implémentation RecyclerView pour utiliser les listes différées dans Compose.

Procédure de migration

Pour migrer votre implémentation RecyclerView vers Compose, procédez comme suit :

  1. Mettez en commentaire ou supprimez RecyclerView de la hiérarchie de l'interface utilisateur, puis ajoutez un ComposeView pour le remplacer s'il n'y en a pas encore dans la hiérarchie. Il s'agit du conteneur de la liste Lazy que vous allez ajouter :

          <FrameLayout
              android:layout_width="match_parent"
              android:layout_height="match_parent">
    
      <!--    <androidx.recyclerview.widget.RecyclerView-->
      <!--            android:id="@+id/recycler_view"-->
      <!--            android:layout_width="match_parent"-->
      <!--            android:layout_height="match_parent />"-->
    
              <androidx.compose.ui.platform.ComposeView
                  android:id="@+id/compose_view"
                  android:layout_width="match_parent"
                  android:layout_height="match_parent" />
    
          </FrameLayout>
    
  2. Déterminez le type de composable de liste différée dont vous avez besoin en fonction du gestionnaire de mise en page de votre RecyclerView (voir le tableau ci-dessous). Le composable que vous sélectionnez sera le composable de premier niveau du ComposeView que vous avez ajouté à l'étape précédente.

    LayoutManager

    Composable

    LinearLayoutManager

    LazyColumn ou LazyRow

    GridLayoutManager

    LazyVerticalGrid ou LazyHorizontalGrid

    StaggeredGridLayoutManager

    LazyVerticalStaggeredGrid ou LazyHorizontalStaggeredGrid

    // recyclerView.layoutManager = LinearLayoutManager(context)
    composeView.setContent {
        LazyColumn(Modifier.fillMaxSize()) {
            // We use a LazyColumn since the layout manager of the RecyclerView is a vertical LinearLayoutManager
        }
    }

  3. Créez un composable correspondant pour chaque type de vue dans votre implémentation de RecyclerView.Adapter. Chaque type de vue correspond généralement à une sous-classe ViewHolder, même si ce n'est pas toujours le cas. Ces composables seront utilisés comme représentation de l'interface utilisateur pour différents types d'éléments de votre liste :

    @Composable
    fun ListItem(data: MyData, modifier: Modifier = Modifier) {
        Row(modifier.fillMaxWidth()) {
            Text(text = data.name)
            // … other composables required for displaying `data`
        }
    }

    La logique des méthodes onCreateViewHolder() et onBindViewHolder() de votre RecyclerView.Adapter sera remplacée par ces composables et l'état que vous leur fournissez. Dans Compose, il n'y a pas de séparation entre la création d'un composable pour un élément et la liaison de données dans celui-ci. Ces concepts sont fusionnés.

  4. Dans l'emplacement content de la liste différée (le paramètre lambda de fin), utilisez la fonction items() (ou une surcharge équivalente) pour itérer les données de votre liste. Dans le lambda itemContent, appelez l'élément composable approprié pour vos données :

    val data = listOf<MyData>(/* ... */)
    composeView.setContent {
        LazyColumn(Modifier.fillMaxSize()) {
            items(data) {
                ListItem(it)
            }
        }
    }

Cas d'utilisation courants

Décorations d'éléments

RecyclerView utilise le concept d'ItemDecoration, que vous pouvez utiliser pour ajouter un dessin spécial aux éléments de la liste. Par exemple, vous pouvez ajouter un ItemDecoration pour ajouter des séparateurs entre les éléments :

val itemDecoration = DividerItemDecoration(recyclerView.context, LinearLayoutManager.VERTICAL)
recyclerView.addItemDecoration(itemDecoration)

Compose n'a pas de concept équivalent de décorations d'éléments. À la place, vous pouvez ajouter n'importe quelle décoration d'UI de la liste directement dans la composition. Par exemple, pour ajouter des séparateurs à la liste, vous pouvez utiliser le composable Divider après chaque élément :

LazyColumn(Modifier.fillMaxSize()) {
    itemsIndexed(data) { index, d ->
        ListItem(d)
        if (index != data.size - 1) {
            HorizontalDivider()
        }
    }
}

Animation des éléments

Un ItemAnimator peut être défini sur un RecyclerView pour animer l'apparence des éléments à mesure que des modifications sont apportées à l'adaptateur. Par défaut, RecyclerView utilise DefaultItemAnimator, qui fournit des animations de base pour les événements de suppression, d'ajout et de déplacement.

Les listes différées ont un concept similaire via le modificateur animateItemPlacement. Pour en savoir plus, consultez Animations d'éléments.

Ressources supplémentaires

Pour en savoir plus sur la migration d'un RecyclerView vers Compose, consultez les ressources suivantes :