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

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

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

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

Ленивые списки имеют аналогичную концепцию благодаря модификатору animateItemPlacement . Дополнительную информацию см. в разделе Анимация предметов .

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

Дополнительные сведения о переносе RecyclerView в Compose см. в следующих ресурсах:

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