Cómo migrar RecyclerView a lista diferida

RecyclerView es un componente View que facilita que se muestren de manera eficiente grandes conjuntos de datos. En lugar de crear vistas para cada elemento del conjunto de datos, RecyclerView mejora el rendimiento de tu app manteniendo un pequeño grupo de vistas y reciclándolas a medida que te desplazas por esos elementos.

En Compose, puedes usar listas Lazy para lograr lo mismo. En esta página, se describe cómo puedes migrar tu implementación de RecyclerView para usar listas Lazy en Compose.

Pasos de la migración

Para migrar tu implementación de RecyclerView a Compose, sigue estos pasos:

  1. Comenta o quita el RecyclerView de tu jerarquía de IU y agrega un ComposeView para reemplazarlo si aún no está presente en la jerarquía. Este es el contenedor de la lista Lazy que agregarás:

          <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. Determina qué tipo de elemento componible de lista Lazy necesitas según el administrador de diseño de tu RecyclerView (consulta la siguiente tabla). El elemento componible que selecciones será el elemento componible de nivel superior del ComposeView que agregaste en el paso anterior.

    LayoutManager

    Componible

    LinearLayoutManager

    LazyColumn o LazyRow

    GridLayoutManager

    LazyVerticalGrid o LazyHorizontalGrid

    StaggeredGridLayoutManager

    LazyVerticalStaggeredGrid o 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. Crea un elemento componible correspondiente para cada tipo de vista en tu implementación de RecyclerView.Adapter. Por lo general, cada tipo de vista se asigna a una subclase ViewHolder, aunque no siempre es así. Estos elementos componibles se usarán como la representación de la IU para diferentes tipos de elementos en tu lista:

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

    La lógica de los métodos onCreateViewHolder() y onBindViewHolder() de tu RecyclerView.Adapter se reemplazará por estos elementos componibles y el estado que les proporciones. En Compose, no hay separación entre crear un elemento componible para un elemento y vincular datos a él; estos conceptos se fusionan.

  4. Dentro del slot content de la lista Lazy (el parámetro lambda final), usa la función items() (o una sobrecarga equivalente) para iterar a través de los datos de tu lista. En la expresión lambda itemContent, invoca el elemento componible adecuado para tus datos:

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

Casos de uso habituales

Decoraciones de elementos

RecyclerView tiene el concepto de un ItemDecoration, que puedes usar para agregar un dibujo especial para los elementos de la lista. Por ejemplo, puedes agregar un ItemDecoration para agregar divisores entre elementos:

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

Compose no tiene un concepto equivalente de decoraciones de elementos. En cambio, puedes agregar cualquier decoración de IU en la lista directamente en la composición. Por ejemplo, para agregar divisores a la lista, puedes usar el elemento componible Divider después de cada elemento:

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

Animaciones de elementos

Se puede configurar un ItemAnimator en un RecyclerView para animar la apariencia de los elementos a medida que se realizan cambios en el adaptador. De forma predeterminada, RecyclerView usa DefaultItemAnimator que proporciona animaciones básicas en eventos de eliminación, adición y movimiento.

Las listas Lazy tienen un concepto similar a través del modificador animateItemPlacement. Consulta Animaciones de elementos para obtener más información.

Recursos adicionales

Para obtener más información sobre cómo migrar un RecyclerView a Compose, consulta los siguientes recursos: