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

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

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

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

Для переноса вашей реализации RecyclerView в Compose выполните следующие шаги:

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

          <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 ленивого списка (завершающий параметр лямбда-функции) используйте функцию 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 см. следующие ресурсы:

{% verbatim %} {% endverbatim %} {% verbatim %} {% endverbatim %}