Przenoszenie widoku RecyclerView do listy Leniwo

RecyclerView to komponent View, który ułatwia efektywne wyświetlanie dużych zbiorów danych. Zamiast tworzyć widoki dla każdego elementu w zbiorze danych, RecyclerViewzwiększa wydajność aplikacji, utrzymując małą pulę widoków i wykorzystując je ponownie podczas przewijania tych elementów.

W Compose możesz użyć list leniwych, aby osiągnąć ten sam efekt. Na tej stronie opisujemy, jak przenieść implementację RecyclerView, aby używać list leniwych w Compose.

Etapy migracji

Aby przenieść implementację RecyclerView do Compose, wykonaj te czynności:

  1. Zakomentuj lub usuń element RecyclerView z hierarchii interfejsu i dodaj element ComposeView, jeśli nie ma go jeszcze w hierarchii. Oto kontener listy leniwej, który dodasz:

          <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. Określ, jakiego typu funkcji kompozycyjnej Lazy list potrzebujesz na podstawie menedżera układu RecyclerView (patrz tabela poniżej). Wybrany komponent będzie komponentem najwyższego poziomu w ComposeView dodanym w poprzednim kroku.

    LayoutManager

    Kompozycyjne

    LinearLayoutManager

    LazyColumn lub LazyRow

    GridLayoutManager

    LazyVerticalGrid lub LazyHorizontalGrid

    StaggeredGridLayoutManager

    LazyVerticalStaggeredGrid lub 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. Utwórz odpowiedni komponent kompozycyjny dla każdego typu widoku w implementacji RecyclerView.Adapter. Każdy typ widoku jest zwykle mapowany na podklasę ViewHolder, ale nie zawsze tak jest. Te komponenty kompozycyjne będą używane jako reprezentacja interfejsu różnych typów elementów na liście:

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

    Logika w metodach RecyclerView.AdapteronCreateViewHolder()onBindViewHolder() zostanie zastąpiona przez te funkcje kompozycyjne i stan, który im przekazujesz. W Compose nie ma rozróżnienia między tworzeniem komponentu kompozycyjnego dla elementu a powiązaniem z nim danych – te pojęcia są połączone.

  4. content gnieździe listy Lazy (ostatni parametr lambda) użyj funkcji items() (lub równoważnego przeciążenia), aby iterować po danych listy. W funkcji itemContent lambda wywołaj odpowiedni element kompozycyjny dla swoich danych:

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

Częste przypadki użycia

Dekoracje produktów

RecyclerView ma koncepcję ItemDecoration, której możesz użyć, aby dodać specjalny rysunek do elementów na liście. Możesz na przykład dodać znak ItemDecoration, aby wstawić separatory między elementami:

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

Compose nie ma odpowiednika dekoracji elementów. Zamiast tego możesz dodać dowolne elementy dekoracyjne interfejsu z listy bezpośrednio w kompozycji. Aby na przykład dodać separatory do listy, możesz użyć funkcji kompozycyjnej Divider po każdym elemencie:

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

Animacje elementów

ItemAnimator można ustawić na RecyclerView, aby animować pojawianie się elementów w miarę wprowadzania zmian w adapterze. Domyślnie RecyclerView używa DefaultItemAnimator, która zapewnia podstawowe animacje podczas usuwania, dodawania i przenoszenia zdarzeń.

Listy leniwe mają podobną koncepcję dzięki modyfikatorowi animateItemPlacement. Więcej informacji znajdziesz w sekcji Animacje elementów.

Dodatkowe materiały

Więcej informacji o migracji RecyclerView do Compose znajdziesz w tych materiałach: