Przenoszenie widoku RecyclerView do listy Leniwo

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

W sekcji „Tworzenie” możesz użyć listy leniwych, aby osiągnąć ten sam efekt. Na tej stronie opisaliśmy, jak przenieść implementację RecyclerView na korzystanie z list opóźnionych w Compose.

Etapy migracji

Aby przenieść implementację RecyclerView do Compose:

  1. Wykomentuj lub usuń element RecyclerView z hierarchii interfejsu użytkownika i w jego miejsce dodaj element ComposeView, jeśli w hierarchii nie ma jeszcze żadnego elementu. To jest kontener dla listy Lazy, którą 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. Na podstawie menedżera układu RecyclerView określ, jakiego typu komponent Lazy List jest Ci potrzebny (patrz tabela poniżej). Wybrany element kompozycyjny będzie najwyższego poziomu na podstawie funkcji ComposeView dodanej w poprzednim kroku.

    LayoutManager

    Kompozycja

    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 w swojej implementacji RecyclerView.Adapter odpowiedni element kompozycyjny dla każdego typu widoku. Każdy typ widoku jest zwykle mapowany na podklasę ViewHolder, ale nie zawsze tak jest. Te elementy będą używane jako reprezentacja interfejsu dla 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 metod onCreateViewHolder()onBindViewHolder() klasy RecyclerView.Adapter zostanie zastąpiona przez te komponenty i stan, które im przekażesz. W komponowaniu nie ma rozróżnienia między tworzeniem komponentu dla elementu a wiązaniem danych z tym elementem – te dwa zagadnienia są ze sobą połączone.

  4. W miejscu content na liście Lazy (ostatni parametr lambda) użyj funkcji items() (lub jej równoważnika) do iterowania po danych na liście. W funkcji itemContent lambda wywołaj odpowiedni element składany dla swoich danych:

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

Częste zastosowania

Dekoracje

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

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

W funkcji Compose nie ma odpowiednika dekoracji produktu. Zamiast tego możesz dodawać elementy dekoracyjne interfejsu na liście bezpośrednio w kompozycji. Aby na przykład dodać do listy separatory, możesz użyć kompozytu Divider po każdym elemencie:

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

Animacje elementów

Aby animować wygląd elementów po wprowadzeniu zmian w adapterze, można ustawić ItemAnimator w elemencie RecyclerView. Domyślnie RecyclerView używa komponentu DefaultItemAnimator, który udostępnia podstawowe animacje zdarzeń usuwania, dodawania i przenoszenia.

Leniwe listy działają podobnie za pomocą modyfikatora animateItemPlacement. Więcej informacji znajdziesz w artykule Animacje elementów.

Dodatkowe materiały

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