Перенос RecyclerView в ленивый список

RecyclerView — это компонент View, который упрощает эффективное отображение больших наборов данных. Вместо того, чтобы создавать представления для каждого элемента в наборе данных, RecyclerView повышает производительность вашего приложения, поддерживая небольшой набор представлений и циклически переключаясь между ними при прокрутке элементов.

В Compose вы можете использовать ленивые списки для достижения той же цели. На этой странице описывается, как перенести реализацию RecyclerView для использования ленивых списков в Compose.

Этапы миграции

Чтобы перенести реализацию RecyclerView в Compose, выполните следующие действия:

  1. Закомментируйте или удалите RecyclerView из иерархии пользовательского интерфейса и добавьте ComposeView для его замены, если его ещё нет в иерархии. Это контейнер для ленивого списка, который вы добавите:

          <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. Определите, какой тип компонуемого элемента «Ленивый список» вам нужен, используя менеджер компоновки вашего RecyclerView (см. таблицу ниже). Выбранный вами компонуемый элемент будет компонуемым элементом верхнего уровня для ComposeView добавленного на предыдущем шаге.

    LayoutManager

    Композитный

    LinearLayoutManager

    LazyColumn или LazyRow

    GridLayoutManager

    LazyVerticalGrid или LazyHorizontalGrid

    StaggeredGridLayoutManager

    LazyVerticalStaggeredGrid или 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. Создайте соответствующий компонуемый элемент для каждого типа представления в вашей реализации RecyclerView.Adapter . Каждый тип представления обычно соответствует подклассу ViewHolder , хотя это может быть не всегда так. Эти компонуемые элементы будут использоваться в качестве пользовательского интерфейса для различных типов элементов в вашем списке:

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

    Логика методов onCreateViewHolder() и onBindViewHolder() вашего RecyclerView.Adapter будет заменена этими компонуемыми объектами и состоянием, которое вы им предоставите. В Compose нет разделения между созданием компонуемого объекта для элемента и привязкой к нему данных — эти концепции объединены.

  4. В слоте content списка Lazy (завершающий лямбда-параметр) используйте функцию items() (или эквивалентную перегрузку) для итерации по данным списка. В лямбда- itemContent вызовите соответствующий компонуемый элемент для ваших данных:

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

Распространенные варианты использования

Украшения предметов

RecyclerView реализована концепция ItemDecoration , которую можно использовать для добавления специального оформления к элементам в списке. Например, можно добавить ItemDecoration для создания разделителей между элементами:

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

В Compose нет аналогичной концепции оформления элементов. Вместо этого вы можете добавлять любые элементы пользовательского интерфейса в список непосредственно в процессе композиции. Например, чтобы добавить разделители в список, можно использовать компонуемый элемент Divider после каждого элемента:

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

Анимации предметов

Для RecyclerView можно настроить ItemAnimator для анимации внешнего вида элементов при внесении изменений в адаптер. По умолчанию RecyclerView использует DefaultItemAnimator , который обеспечивает базовую анимацию при удалении, добавлении и перемещении.

В ленивых списках используется аналогичная концепция благодаря модификатору animateItemPlacement . Подробнее см. в разделе «Анимация элементов» .

Дополнительные ресурсы

Дополнительную информацию о переносе RecyclerView в Compose можно найти в следующих ресурсах:

{% дословно %} {% endverbatim %} {% дословно %} {% endverbatim %}