Dari https://developer.android.com/preview/material/ui-widgets.html
Ketika kita membuat RecyclerView.Adapter
kita harus menentukan ViewHolder
yang akan mengikat dengan adaptor.
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
private String[] mDataset;
public MyAdapter(String[] myDataset) {
mDataset = myDataset;
}
public static class ViewHolder extends RecyclerView.ViewHolder {
public TextView mTextView;
public ViewHolder(TextView v) {
super(v);
mTextView = v;
}
}
@Override
public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.some_layout, parent, false);
//findViewById...
ViewHolder vh = new ViewHolder(v);
return vh;
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.mTextView.setText(mDataset[position]);
}
@Override
public int getItemCount() {
return mDataset.length;
}
}
Jadi, apakah mungkin membuat RecyclerView
dengan beberapa jenis tampilan?
Jawaban:
Iya itu mungkin. Cukup terapkan getItemViewType () , dan urus
viewType
parameter dionCreateViewHolder()
.Jadi Anda melakukan sesuatu seperti:
sumber
optionMenuItem
. Bagaimana mungkin? @AntonSavinJika tata letak untuk jenis tampilan hanya sedikit dan logika pengikat sederhana, ikuti solusi Anton.
Tetapi kodenya akan berantakan jika Anda perlu mengatur tata letak yang rumit dan logika yang mengikat.
Saya percaya solusi berikut ini akan berguna bagi seseorang yang perlu menangani tipe tampilan yang kompleks.
Kelas Basis DataBinder
Fungsi yang diperlukan untuk mendefinisikan di kelas ini hampir sama dengan kelas adaptor saat membuat tipe tampilan tunggal.
Untuk setiap jenis tampilan, buat kelas dengan memperluas DataBinder ini.
Contoh kelas DataBinder
Untuk mengelola kelas DataBinder, buat kelas adaptor.
Basiskan kelas DataBindAdapter
Buat kelas dengan memperluas kelas dasar ini, dan kemudian instantiate kelas DataBinder dan timpa metode abstrak
getItemCount
Mengembalikan total jumlah item dari DataBinders
getItemViewType
Tentukan logika pemetaan antara posisi adaptor dan jenis tampilan.
getDataBinder
Mengembalikan instance DataBinder berdasarkan tipe tampilan
getPosition
Tentukan logika konversi ke posisi adaptor dari posisi di DataBinder yang ditentukan
getBinderPosition
Tentukan logika konversi ke posisi di DataBinder dari posisi adaptor
Semoga solusi ini bermanfaat.
Saya meninggalkan solusi dan sampel yang lebih detail di GitHub, jadi silakan merujuk tautan berikut jika Anda perlu.
https://github.com/yqritc/RecyclerView-MultipleViewTypesAdapter
sumber
public class DataBinder<T extends RecyclerView.ViewHolder>
bisakah seseorang memberi tahu saya apa<T someClass>
yang disebut, jadi saya bisa google jika saya mendapatkan istilah. Juga ketika saya mengatakanabstract public class DataBinder<T extends RecyclerView.ViewHolder>
apakah itu berarti bahwa kelas ini bertipeViewHolder
, jadi pada akhirnya setiap kelas yang memperluas kelas ini bertipeviewHolder
apakah itu idenya?Di bawah ini bukan pseudocode dan saya telah mengujinya dan telah bekerja untuk saya.
Saya ingin membuat headerview di recyclerview saya dan kemudian menampilkan daftar gambar di bawah header yang bisa diklik pengguna.
Saya menggunakan beberapa sakelar dalam kode saya, tidak tahu apakah itu cara paling efisien untuk melakukan ini, jadi jangan ragu untuk memberikan komentar Anda:
sumber
Ya itu mungkin.
Tulis pemegang tampilan umum:
kemudian buat pemegang tampilan Anda dan buat mereka memperpanjang GenericViewHolder. Misalnya, ini:
maka kelas RecyclerView.Adapter akan terlihat seperti ini:
sumber
Buat ViewHolder yang berbeda untuk tata letak yang berbeda
RecyclerView dapat memiliki jumlah pemirsa yang Anda inginkan tetapi untuk keterbacaan yang lebih baik mari kita lihat cara membuat satu dengan dua ViewHolders.
public int getItemViewType(int position)
onCreateViewHolder()
metode ViewType dalamonBindViewHolder()
metodeBerikut ini cuplikan kode kecil
getItemViewType (posisi int) adalah kuncinya
Menurut pendapat saya, titik awal untuk membuat jenis recyclerView ini adalah pengetahuan tentang metode ini. Karena metode ini opsional untuk ditimpa oleh karena itu tidak terlihat di kelas RecylerView secara default yang pada gilirannya membuat banyak pengembang (termasuk saya) bertanya-tanya harus mulai dari mana. Setelah Anda mengetahui bahwa metode ini ada, membuat RecyclerView seperti itu akan menjadi cakewalk.
Tautan yang Relevan:
Lihatlah proyek tempat saya menerapkan ini
sumber
Ya itu mungkin. Di adaptor Anda, getItemViewType Layout seperti ini ....
untuk tautan referensi: https://www.journaldev.com/12372/android-recyclerview-example
sumber
mengikuti solusi Anton, buat ini
ViewHolder
yang menampung / menangani / mendelegasikan berbagai jenis tata letak. Tetapi tidak yakin apakah mengganti tata letak baru akan berfungsi saat tampilan daur ulangViewHolder
bukan tipe data roll in.Jadi pada dasarnya,
onCreateViewHolder(ViewGroup parent, int viewType)
hanya dipanggil ketika tata letak tampilan baru diperlukan;getItemViewType(int position)
akan dipanggil untukviewType
;onBindViewHolder(ViewHolder holder, int position)
selalu dipanggil saat mendaur ulang tampilan (data baru dibawa dan coba ditampilkan dengan ituViewHolder
).Jadi ketika
onBindViewHolder
dipanggil perlu diletakkan di tata letak tampilan yang benar dan perbaruiViewHolder
.Apakah cara yang benar untuk mengganti tata letak tampilan untuk yang
ViewHolder
akan dibawa, atau masalah? Hargai komentar apa pun!Sunting: ViewHolder memiliki anggota mItemViewType untuk menahan tampilan
Sunting: terlihat seperti pada onBindViewHolder (pemegang ViewHolder, posisi int) ViewHolder yang disahkan telah diambil (atau dibuat) dengan melihat getItemViewType (posisi int) untuk memastikan itu cocok, jadi mungkin tidak perlu khawatir di sana bahwa ViewHolder's tipe tidak cocok dengan tipe data [posisi]. Adakah yang tahu lebih banyak bagaimana ViewHolder di onBindViewHolder () diambil?
Edit: Sepertinya daur ulang
ViewHolder
dipilih berdasarkan jenis, jadi tidak ada prajurit di sana.Edit: http://wiresareobsolete.com/2014/09/building-a-recyclerview-layoutmanager-part-1/ menjawab pertanyaan ini.
Mendapat daur ulang
ViewHolder
seperti:atau buat yang baru jika tidak menemukan daur ulang
ViewHolder
dari jenis yang tepat.sumber
Saya memiliki solusi yang lebih baik yang memungkinkan untuk membuat beberapa tipe tampilan dengan cara deklaratif dan tipe aman. Itu ditulis dalam Kotlin yang btw sangat bagus.
Pemegang tampilan sederhana untuk semua jenis tampilan yang diperlukan
Ada abstraksi dari item data adaptor. Perhatikan bahwa tipe tampilan diwakili oleh kode hash dari kelas pemegang tampilan tertentu (KClass di Kotlin)
Hanya
bindViewHolder
perlu diganti dalam kelas item adaptor beton (ketik cara aman)Daftar
AdapterItemMedium
objek tersebut adalah sumber data untuk adaptor yang benar-benar menerimaList<AdapterItem>
lihat di bawah.Bagian penting dari solusi ini adalah pabrik pemegang pandangan yang akan memberikan contoh baru dari ViewHolder tertentu
Dan kelas adaptor sederhana terlihat seperti ini
Hanya 3 langkah untuk membuat tipe tampilan baru:
ViewHolderProvider
Berikut ini adalah contoh dari konsep ini: android-drawer-template Lebih jauh lagi - tipe tampilan yang bertindak sebagai komponen pemintal, item adaptor yang dapat dipilih.
sumber
Ini sangat sederhana dan lurus ke depan.
Hanya Ganti metode getItemViewType () di adaptor Anda. Atas dasar data mengembalikan nilai itemViewType yang berbeda. mis. Pertimbangkan objek bertipe Person dengan anggota isMale, jika isMale benar, kembalikan 1 dan isMale salah, kembalikan 2 di getItemViewType () metode .
Sekarang sampai pada createViewHolder (induk ViewGroup, int viewType) , berdasarkan berbagai tipe tampilan Anda dapat mengembang file tata letak yang berbeda. seperti berikut ini
di onBindViewHolder (pemegang VH, posisi int) periksa di mana pemegang adalah instance dari
AdapterFemaleViewHolder
atauAdapterMaleViewHolder
olehinstanceof
dan dengan demikian tetapkan nilainya.ViewHolder Mungkin seperti ini
sumber
Meskipun jawaban yang dipilih benar, saya hanya ingin menjelaskannya lebih lanjut. Saya menemukan di sini Adaptor Kustom yang berguna untuk beberapa Jenis Tampilan di RecyclerView . Its versi Kotlin sini .
Adaptor Kustom berikut
sumber
Saya merekomendasikan perpustakaan ini dari Hannes Dorfmann. Itu merangkum semua logika yang terkait dengan jenis tampilan tertentu dalam objek terpisah yang disebut "AdapterDelegate". https://github.com/sockeqwe/AdapterDelegates
sumber
Sebenarnya, saya ingin memperbaiki jawaban Anton .
Karena
getItemViewType(int position)
mengembalikan nilai integer, Anda dapat mengembalikan ID sumber daya tata letak yang harus Anda kembangkan. Dengan begitu Anda akan menghemat beberapa logika dalamonCreateViewHolder(ViewGroup parent, int viewType)
metode.Juga, saya tidak akan menyarankan melakukan perhitungan intensif
getItemCount()
karena fungsi tertentu dipanggil setidaknya 5 kali saat merender daftar, serta saat merender setiap item di luar item yang terlihat. Sayangnya karenanotifyDatasetChanged()
metode ini final, Anda tidak dapat benar-benar menimpanya, tetapi Anda dapat memanggilnya dari fungsi lain di dalam adaptor.sumber
Note: Integers must be in the range 0 to getViewTypeCount() - 1. IGNORE_ITEM_VIEW_TYPE can also be returned.
Jadi lebih baik menulis sedikit lebih banyak kode dan tidak menggunakan peretasan.Anda dapat menggunakan perpustakaan: https://github.com/vivchar/RendererRecyclerViewAdapter
`
Untuk setiap item, Anda harus menerapkan ViewRenderer, ViewHolder, SomeModel:
ViewHolder - ini adalah pemegang tampilan sederhana dari pendaur ulang.
SomeModel - ini adalah model Anda dengan
ItemModel
antarmukaUntuk lebih jelasnya Anda bisa melihat dokumentasi.
sumber
Lihat jenis implementasi menjadi lebih mudah dengan kotlin, berikut adalah contoh dengan perpustakaan ringan ini https://github.com/Link184/KidAdapter
sumber
Anda dapat menangani multipleViewTypes
RecyclerAdapter
oleh pembuatangetItemViewType()
mengembalikan diharapkanviewType
nilai untuk posisi tersebutSaya menyiapkan sebuah
MultipleViewTypeAdapter
untuk menyusun daftar soal pilihan ganda untuk ujian yang dapat mengajukan pertanyaan yang mungkin memiliki 2 atau lebih jawaban yang valid (opsi kotak centang) dan satu pertanyaan jawaban tunggal (opsi radiobutton).Untuk ini saya mendapatkan jenis Pertanyaan dari respons API dan saya menggunakannya untuk memutuskan tampilan mana yang harus saya tunjukkan untuk pertanyaan itu.
Anda dapat menghindari beberapa pengisian data viewHolder berbasis kondisional
onBindViewHolder()
dengan menetapkan id yang sama untuk tampilan serupa di viewHolder yang berbeda dalam penentuan posisi.sumber
Jika Anda ingin menggunakannya bersamaan dengan tampilan Pengikatan Data Android ke https://github.com/evant/binding-collection-adapter - ini adalah solusi terbaik untuk berbagai jenis tampilan.
RecyclerView
bahkan pernah saya lihat.Anda dapat menggunakannya seperti
dan kemudian di tata letak di mana daftar berada
item daftar Anda harus mengimplementasikan
BaseListItem
antarmuka yang terlihat seperti inidan tampilan barang akan terlihat seperti ini
Di mana
YourListItem
mengimplementasikanBaseListItem
Semoga ini bisa membantu seseorang.
sumber
pertama Anda harus membuat 2 layout xml. setelah itu di dalam adapter recyclerview, TYPE_CALL dan TYPE_EMAIL adalah dua nilai statis dengan masing-masing 1 dan 2 di kelas adaptor.
sekarang Tetapkan dua nilai statis pada tingkat kelas Adaptor pandangan Recycler misalnya: private static int TYPE_CALL = 1; private static int TYPE_EMAIL = 2;
Sekarang buat pemegang tampilan dengan banyak tampilan seperti ini:
Sekarang kode seperti di bawah ini di metode onCreateViewHolder dan onBindViewHolder di adaptor recyclerview:
sumber