Twórz dynamiczne listy za pomocą RecyclerView. Zawiera Android Jetpack.

Wypróbuj sposób tworzenia wiadomości
Jetpack Compose to zalecany zestaw narzędzi UI na Androida. Dowiedz się, jak korzystać z układów w funkcji Utwórz

RecyclerView ułatwia efektywne wyświetlanie dużych zbiorów danych. Wystarczy podać dane i określić wygląd każdego elementu, a biblioteka RecyclerView dynamicznie tworzy te elementy, gdy są potrzebne.

Jak wskazuje nazwa, element RecyclerView recyklinguje te pojedyncze elementy. Gdy element przewinie się poza ekran, element RecyclerView nie zniszczy jego widoku. Zamiast tego obiekt RecyclerView będzie ponownie wykorzystywać widok do tworzenia nowych elementów, które zostały przewinięte na ekran. Funkcja RecyclerView zwiększa wydajność i czas reagowania aplikacji, a także zmniejsza zużycie energii.

Kluczowe klasy

Kilka zajęć musi ze sobą współpracować, by utworzyć dynamiczną listę.

  • RecyclerView to ViewGroup, który zawiera widoki odpowiadające Twoim danym. To sam widok, więc dodajesz RecyclerView do układu w taki sam sposób, w jaki dodajesz inne elementy interfejsu.

  • Każdy element na liście jest definiowany przez obiekt obiektu widoku. Po utworzeniu właściciela widoku nie są z nim powiązane żadne dane. Po utworzeniu właściciela widoku obiekt RecyclerView wiąże go ze swoimi danymi. Uchwyt widoku definiuje się przez rozszerzenie widoku RecyclerView.ViewHolder.

  • RecyclerView żąda widoków i wiąże je z ich danymi, wywołując metody w adapterze. Definiujesz adapter, przedłużając ciąg RecyclerView.Adapter.

  • Menedżer układu porządkuje poszczególne elementy na liście. Możesz użyć jednego z menedżerów układu dostępnych w bibliotece RecyclerView lub zdefiniować własne. Menedżerowie układu są oparte na klasie abstrakcyjnej LayoutManager biblioteki.

Aby zobaczyć, jak wszystkie elementy się ze sobą łączą, skorzystaj z przykładowej aplikacji RecyclerView (Kotlin) lub przykładowej aplikacji RecyclerView (Java).

Etapy wdrażania elementu RecyclerView

Jeśli zamierzasz użyć obiektu RecyclerView, musisz wykonać kilka czynności. Zostały one szczegółowo wyjaśnione w kolejnych sekcjach.

  1. Wybierz wygląd listy lub siatki. Zwykle można użyć jednego z menedżerów układu dostępnych w bibliotece RecyclerView.

  2. Zaprojektuj, jak każdy element na liście wygląda i działa. Biorąc pod uwagę ten projekt, rozszerz klasę ViewHolder. Twoja wersja ViewHolder udostępnia wszystkie funkcje elementów listy. Obiekt widoku danych łączy się z elementem View, a tym widokiem zarządza RecyclerView.

  3. Określ Adapter, który wiąże Twoje dane z widokami ViewHolder.

Dostępne są też zaawansowane opcje dostosowywania, które umożliwiają dostosowanie widoku RecyclerView do własnych potrzeb.

Planowanie układu

Elementy w obiekcie RecyclerView są uporządkowane według klasy LayoutManager. Biblioteka RecyclerView zawiera 3 menedżery układu, które obsługują najczęstsze sytuacje związane z układami:

  • LinearLayoutManager uporządkuje elementy na jednowymiarowej liście.
  • GridLayoutManager układa elementy w dwuwymiarową siatkę:
    • Jeśli siatka jest ustawiona w pionie, GridLayoutManager stara się, aby wszystkie elementy w każdym wierszu miały taką samą szerokość i wysokość, ale różne wiersze mogą mieć różną wysokość.
    • Jeśli siatka jest ustawiona w poziomie, GridLayoutManager stara się, aby wszystkie elementy w każdej kolumnie miały taką samą szerokość i wysokość, ale różne kolumny mogą mieć różną szerokość.
  • StaggeredGridLayoutManager działa podobnie do GridLayoutManager, ale nie wymaga, aby elementy w wierszu miały taką samą wysokość (w przypadku siatek pionowych) ani elementy w tej samej kolumnie (w przypadku siatek poziomych). W efekcie elementy w wierszu lub kolumnie mogą być od siebie przesunięte.

Musisz też zaprojektować układ poszczególnych elementów. Ten układ jest potrzebny podczas projektowania uchwytu widoku, jak opisano w następnej sekcji.

Wdrażanie adaptera i uchwytu widoku

Po określeniu układu musisz wdrożyć Adapter i ViewHolder. Te 2 klasy wspólnie określają sposób wyświetlania danych. ViewHolder to otoka wokół elementu View, która zawiera układ konkretnego elementu na liście. W razie potrzeby Adapter tworzy obiekty ViewHolder i ustawia dane dla tych widoków. Proces wiązania widoków danych z ich danymi nazywa się wiązywaniem.

Gdy definiujesz adapter, zastępujesz trzy kluczowe metody:

  • onCreateViewHolder(): RecyclerView wywołuje tę metodę za każdym razem, gdy trzeba utworzyć nowy obiekt ViewHolder. Ta metoda tworzy i inicjuje obiekt ViewHolder oraz powiązany z nim element View, ale nie wypełnia zawartości widoku – obiekt ViewHolder nie jest jeszcze powiązany z konkretnymi danymi.

  • onBindViewHolder(): funkcja RecyclerView wywołuje tę metodę, aby powiązać element ViewHolder z danymi. Metoda pobiera odpowiednie dane i wykorzystuje je do wypełniania układu właściciela widoku. Jeśli na przykład RecyclerView wyświetla listę nazw, metoda może znaleźć na liście odpowiednią nazwę i wypełnić widżet TextView właściciela widoku.

  • getItemCount(): funkcja RecyclerView wywołuje tę metodę, aby uzyskać rozmiar zbioru danych. Na przykład w aplikacji książki adresowej może to być łączna liczba adresów. Funkcja RecyclerView korzysta z niej, aby określić, kiedy nie ma więcej elementów, które można wyświetlić.

Oto typowy przykład prostego adaptera z zagnieżdżonym obiektem ViewHolder, który wyświetla listę danych. W tym przypadku RecyclerView wyświetla prostą listę elementów tekstowych. Adapter jest przekazywany do tablicy ciągów tekstowych zawierających tekst elementów ViewHolder.

Kotlin


class CustomAdapter(private val dataSet: Array<String>) :
        RecyclerView.Adapter<CustomAdapter.ViewHolder>() {

    /**
     * Provide a reference to the type of views that you are using
     * (custom ViewHolder)
     */
    class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
        val textView: TextView

        init {
            // Define click listener for the ViewHolder's View
            textView = view.findViewById(R.id.textView)
        }
    }

    // Create new views (invoked by the layout manager)
    override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): ViewHolder {
        // Create a new view, which defines the UI of the list item
        val view = LayoutInflater.from(viewGroup.context)
                .inflate(R.layout.text_row_item, viewGroup, false)

        return ViewHolder(view)
    }

    // Replace the contents of a view (invoked by the layout manager)
    override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) {

        // Get element from your dataset at this position and replace the
        // contents of the view with that element
        viewHolder.textView.text = dataSet[position]
    }

    // Return the size of your dataset (invoked by the layout manager)
    override fun getItemCount() = dataSet.size

}

Java


public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.ViewHolder> {

    private String[] localDataSet;

    /**
     * Provide a reference to the type of views that you are using
     * (custom ViewHolder)
     */
    public static class ViewHolder extends RecyclerView.ViewHolder {
        private final TextView textView;

        public ViewHolder(View view) {
            super(view);
            // Define click listener for the ViewHolder's View

            textView = (TextView) view.findViewById(R.id.textView);
        }

        public TextView getTextView() {
            return textView;
        }
    }

    /**
     * Initialize the dataset of the Adapter
     *
     * @param dataSet String[] containing the data to populate views to be used
     * by RecyclerView
     */
    public CustomAdapter(String[] dataSet) {
        localDataSet = dataSet;
    }

    // Create new views (invoked by the layout manager)
    @Override
    public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
        // Create a new view, which defines the UI of the list item
        View view = LayoutInflater.from(viewGroup.getContext())
                .inflate(R.layout.text_row_item, viewGroup, false);

        return new ViewHolder(view);
    }

    // Replace the contents of a view (invoked by the layout manager)
    @Override
    public void onBindViewHolder(ViewHolder viewHolder, final int position) {

        // Get element from your dataset at this position and replace the
        // contents of the view with that element
        viewHolder.getTextView().setText(localDataSet[position]);
    }

    // Return the size of your dataset (invoked by the layout manager)
    @Override
    public int getItemCount() {
        return localDataSet.length;
    }
}

Układ każdego elementu widoku jest jak zwykle zdefiniowany w pliku układu XML. W tym przypadku aplikacja ma plik text_row_item.xml podobny do tego:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="@dimen/list_item_height"
    android:layout_marginLeft="@dimen/margin_medium"
    android:layout_marginRight="@dimen/margin_medium"
    android:gravity="center_vertical">

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/element_text"/>
</FrameLayout>

Dalsze kroki

Poniższy fragment kodu pokazuje, jak korzystać z narzędzia RecyclerView.

Kotlin


class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val dataset = arrayOf("January", "February", "March")
        val customAdapter = CustomAdapter(dataset)

        val recyclerView: RecyclerView = findViewById(R.id.recycler_view)
        recyclerView.layoutManager = LinearLayoutManager(this)
        recyclerView.adapter = customAdapter

    }

}

Java


RecyclerView recyclerView = findViewById(R.id.recycler_view);
recyclerView.layoutManager = new LinearLayoutManager(this)
recyclerView.setAdapter(customAdapter);

Biblioteka umożliwia też dostosowanie implementacji na wiele sposobów. Więcej informacji znajdziesz w artykule na temat zaawansowanych dostosowań elementu RecyclerView.

Dodatkowe materiały

Więcej informacji o testowaniu na Androidzie znajdziesz w tych materiałach.

Przykładowe aplikacje