pengantar
Karena tidak benar-benar jelas dari pertanyaan Anda apa sebenarnya yang Anda hadapi, saya menulis langkah cepat ini tentang bagaimana menerapkan fitur ini; jika Anda masih memiliki pertanyaan, jangan ragu untuk bertanya.
Saya memiliki contoh kerja dari semua yang saya bicarakan di sini di Repositori GitHub ini .
Jika Anda ingin tahu lebih banyak tentang contoh proyek, kunjungi beranda proyek .
Bagaimanapun hasilnya akan terlihat seperti ini:

Jika pertama kali ingin bermain-main dengan aplikasi demo, Anda dapat menginstalnya dari Play Store:

Pokoknya mari kita mulai.
Menyiapkan SearchView
Di dalam folder res/menu buat file baru bernama main_menu.xml. Di dalamnya tambahkan item dan atur actionViewClasske android.support.v7.widget.SearchView. Karena Anda menggunakan pustaka dukungan, Anda harus menggunakan namespace pustaka dukungan untuk mengatur actionViewClassatribut. File xml Anda akan terlihat seperti ini:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:id="@+id/action_search"
android:title="@string/action_search"
app:actionViewClass="android.support.v7.widget.SearchView"
app:showAsAction="always"/>
</menu>
Di Anda Fragmentatau ActivityAnda harus mengembang menu ini xml seperti biasanya, maka Anda dapat mencariMenuItem yang berisi SearchViewdan menerapkan OnQueryTextListeneryang akan kita gunakan untuk mendengarkan perubahan pada teks yang dimasukkan ke SearchView:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
final MenuItem searchItem = menu.findItem(R.id.action_search);
final SearchView searchView = (SearchView) searchItem.getActionView();
searchView.setOnQueryTextListener(this);
return true;
}
@Override
public boolean onQueryTextChange(String query) {
// Here is where we are going to implement the filter logic
return false;
}
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
Dan sekarang SearchViewsudah siap untuk digunakan. Kami akan menerapkan logika filter nanti onQueryTextChange()setelah kami selesai mengimplementasikan Adapter.
Menyiapkan Adapter
Pertama dan terutama, ini adalah kelas model yang akan saya gunakan untuk contoh ini:
public class ExampleModel {
private final long mId;
private final String mText;
public ExampleModel(long id, String text) {
mId = id;
mText = text;
}
public long getId() {
return mId;
}
public String getText() {
return mText;
}
}
Hanya saja model dasar Anda yang akan menampilkan teks di RecyclerView . Ini adalah tata letak yang akan saya gunakan untuk menampilkan teks:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="model"
type="com.github.wrdlbrnft.searchablerecyclerviewdemo.ui.models.ExampleModel"/>
</data>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:clickable="true">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp"
android:text="@{model.text}"/>
</FrameLayout>
</layout>
Seperti yang Anda lihat saya menggunakan Binding Data. Jika Anda belum pernah bekerja dengan pengikatan data sebelum jangan berkecil hati! Ini sangat sederhana dan kuat, namun saya tidak dapat menjelaskan cara kerjanya dalam lingkup jawaban ini.
Ini ViewHolderuntuk ExampleModelkelas:
public class ExampleViewHolder extends RecyclerView.ViewHolder {
private final ItemExampleBinding mBinding;
public ExampleViewHolder(ItemExampleBinding binding) {
super(binding.getRoot());
mBinding = binding;
}
public void bind(ExampleModel item) {
mBinding.setModel(item);
}
}
Sekali lagi tidak ada yang istimewa. Itu hanya menggunakan data yang mengikat untuk mengikat kelas model ke tata letak ini seperti yang telah kita tentukan dalam tata letak xml di atas.
Sekarang kita akhirnya dapat sampai pada bagian yang sangat menarik: Menulis Adaptor. Saya akan melewatkan implementasi dasar dariAdapter dan bukannya akan berkonsentrasi pada bagian-bagian yang relevan untuk jawaban ini.
Tetapi pertama-tama ada satu hal yang harus kita bicarakan: SortedListKelas.
DiurutkanDaftar
Ini SortedListadalah alat yang sangat luar biasa yang merupakan bagian dari RecyclerViewperpustakaan. Ini mengurus pemberitahuan Adaptertentang perubahan set data dan melakukannya dengan cara yang sangat efisien. Satu-satunya hal yang mengharuskan Anda lakukan adalah menentukan urutan elemen. Anda perlu melakukan itu dengan menerapkan compare()metode yang membandingkan dua elemen SortedListseperti a Comparator. Tapi bukannya menyortir Listitu digunakan untuk menyortir item di RecyclerView!
The SortedListberinteraksi dengan Adaptermelalui Callbackkelas yang Anda harus melaksanakan:
private final SortedList.Callback<ExampleModel> mCallback = new SortedList.Callback<ExampleModel>() {
@Override
public void onInserted(int position, int count) {
mAdapter.notifyItemRangeInserted(position, count);
}
@Override
public void onRemoved(int position, int count) {
mAdapter.notifyItemRangeRemoved(position, count);
}
@Override
public void onMoved(int fromPosition, int toPosition) {
mAdapter.notifyItemMoved(fromPosition, toPosition);
}
@Override
public void onChanged(int position, int count) {
mAdapter.notifyItemRangeChanged(position, count);
}
@Override
public int compare(ExampleModel a, ExampleModel b) {
return mComparator.compare(a, b);
}
@Override
public boolean areContentsTheSame(ExampleModel oldItem, ExampleModel newItem) {
return oldItem.equals(newItem);
}
@Override
public boolean areItemsTheSame(ExampleModel item1, ExampleModel item2) {
return item1.getId() == item2.getId();
}
}
Dalam metode di atas callback seperti onMoved, onInserted, dll Anda harus memanggil setara memberitahukan metode Anda Adapter. Tiga metode di bagian bawah compare, areContentsTheSamedanareItemsTheSame Anda harus menerapkan sesuai dengan objek apa yang ingin Anda tampilkan dan dalam urutan apa objek ini akan muncul di layar.
Mari kita pelajari metode ini satu per satu:
@Override
public int compare(ExampleModel a, ExampleModel b) {
return mComparator.compare(a, b);
}
Ini adalah compare()metode yang saya bicarakan sebelumnya. Dalam contoh ini saya hanya meneruskan panggilan ke Comparatoryang membandingkan kedua model. Jika Anda ingin item muncul dalam urutan abjad di layar. Komparator ini mungkin terlihat seperti ini:
private static final Comparator<ExampleModel> ALPHABETICAL_COMPARATOR = new Comparator<ExampleModel>() {
@Override
public int compare(ExampleModel a, ExampleModel b) {
return a.getText().compareTo(b.getText());
}
};
Sekarang mari kita lihat metode selanjutnya:
@Override
public boolean areContentsTheSame(ExampleModel oldItem, ExampleModel newItem) {
return oldItem.equals(newItem);
}
Tujuan metode ini adalah untuk menentukan apakah konten model telah berubah. The SortedListpenggunaan ini untuk menentukan apakah peristiwa perubahan perlu dipanggil - dengan kata lain jika RecyclerViewharus crossfade versi lama dan baru. Jika model Anda memiliki kelas yang benar equals()dan hashCode()implementasi Anda biasanya dapat mengimplementasikannya seperti di atas. Jika kita menambahkan equals()dan hashCode()implementasi ke ExampleModelkelas itu akan terlihat seperti ini:
public class ExampleModel implements SortedListAdapter.ViewModel {
private final long mId;
private final String mText;
public ExampleModel(long id, String text) {
mId = id;
mText = text;
}
public long getId() {
return mId;
}
public String getText() {
return mText;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ExampleModel model = (ExampleModel) o;
if (mId != model.mId) return false;
return mText != null ? mText.equals(model.mText) : model.mText == null;
}
@Override
public int hashCode() {
int result = (int) (mId ^ (mId >>> 32));
result = 31 * result + (mText != null ? mText.hashCode() : 0);
return result;
}
}
Catatan samping cepat: Sebagian besar IDE seperti Android Studio, IntelliJ dan Eclipse memiliki fungsi untuk menghasilkan equals()danhashCode() implementasi untuk Anda dengan menekan satu tombol! Jadi Anda tidak harus menerapkannya sendiri. Cari di internet cara kerjanya di IDE Anda!
Sekarang mari kita lihat metode terakhir:
@Override
public boolean areItemsTheSame(ExampleModel item1, ExampleModel item2) {
return item1.getId() == item2.getId();
}
The SortedListmenggunakan metode ini untuk memeriksa apakah dua item merujuk pada hal yang sama. Dalam istilah yang paling sederhana (tanpa menjelaskan cara SortedListkerjanya) ini digunakan untuk menentukan apakah suatu objek sudah terkandung dalamList dan apakah salah satu dari add, move atau perubahan animasi perlu dimainkan. Jika model Anda memiliki id, Anda biasanya hanya membandingkan id dalam metode ini. Jika tidak, Anda perlu mencari cara lain untuk memeriksanya, tetapi bagaimanapun Anda akhirnya menerapkan ini tergantung pada aplikasi spesifik Anda. Biasanya ini adalah opsi paling sederhana untuk memberikan semua model id - yang misalnya bisa menjadi bidang kunci utama jika Anda meminta data dari database.
Dengan SortedList.Callbackpenerapan yang benar kita dapat membuat instance dari SortedList:
final SortedList<ExampleModel> list = new SortedList<>(ExampleModel.class, mCallback);
Sebagai parameter pertama dalam konstruktor, SortedListAnda harus lulus kelas model Anda. Parameter lainnya hanyalah yang SortedList.Callbackkita definisikan di atas.
Sekarang mari kita mulai ke bisnis: Jika kita menerapkan Adapterdengan SortedListitu akan terlihat seperti ini:
public class ExampleAdapter extends RecyclerView.Adapter<ExampleViewHolder> {
private final SortedList<ExampleModel> mSortedList = new SortedList<>(ExampleModel.class, new SortedList.Callback<ExampleModel>() {
@Override
public int compare(ExampleModel a, ExampleModel b) {
return mComparator.compare(a, b);
}
@Override
public void onInserted(int position, int count) {
notifyItemRangeInserted(position, count);
}
@Override
public void onRemoved(int position, int count) {
notifyItemRangeRemoved(position, count);
}
@Override
public void onMoved(int fromPosition, int toPosition) {
notifyItemMoved(fromPosition, toPosition);
}
@Override
public void onChanged(int position, int count) {
notifyItemRangeChanged(position, count);
}
@Override
public boolean areContentsTheSame(ExampleModel oldItem, ExampleModel newItem) {
return oldItem.equals(newItem);
}
@Override
public boolean areItemsTheSame(ExampleModel item1, ExampleModel item2) {
return item1.getId() == item2.getId();
}
});
private final LayoutInflater mInflater;
private final Comparator<ExampleModel> mComparator;
public ExampleAdapter(Context context, Comparator<ExampleModel> comparator) {
mInflater = LayoutInflater.from(context);
mComparator = comparator;
}
@Override
public ExampleViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
final ItemExampleBinding binding = ItemExampleBinding.inflate(inflater, parent, false);
return new ExampleViewHolder(binding);
}
@Override
public void onBindViewHolder(ExampleViewHolder holder, int position) {
final ExampleModel model = mSortedList.get(position);
holder.bind(model);
}
@Override
public int getItemCount() {
return mSortedList.size();
}
}
The Comparatordigunakan untuk mengurutkan item dilewatkan melalui konstruktor sehingga kita dapat menggunakan yang sama Adapterbahkan jika item yang seharusnya ditampilkan dalam urutan yang berbeda.
Sekarang kita hampir selesai! Tetapi pertama-tama kita perlu cara untuk menambah atau menghapus item ke Adapter. Untuk tujuan ini, kami dapat menambahkan metode Adapteryang memungkinkan kami menambah dan menghapus item ke SortedList:
public void add(ExampleModel model) {
mSortedList.add(model);
}
public void remove(ExampleModel model) {
mSortedList.remove(model);
}
public void add(List<ExampleModel> models) {
mSortedList.addAll(models);
}
public void remove(List<ExampleModel> models) {
mSortedList.beginBatchedUpdates();
for (ExampleModel model : models) {
mSortedList.remove(model);
}
mSortedList.endBatchedUpdates();
}
Kami tidak perlu memanggil metode pemberitahuan apa pun di sini karena SortedListsudah melakukan ini melalui SortedList.Callback! Selain itu penerapan metode ini cukup mudah dengan satu pengecualian: metode hapus yang menghilangkan Listmodel. Karena SortedListhanya memiliki satu metode hapus yang dapat menghapus satu objek, kita perlu mengulang daftar dan menghapus model satu per satu. Memanggil beginBatchedUpdates()dari awal akan SortedListmengumpulkan semua perubahan yang akan kita lakukan untuk bersama dan meningkatkan kinerja. Ketika kita sebut endBatchedUpdates()denganRecyclerView diberitahukan tentang semua perubahan sekaligus.
Selain itu apa yang harus Anda pahami adalah bahwa jika Anda menambahkan objek ke SortedListdan sudah ada di SortedListdalamnya tidak akan ditambahkan lagi. Alih-alih SortedListmenggunakan areContentsTheSame()metode untuk mencari tahu apakah objek telah berubah - dan jika memiliki item dalam RecyclerViewakan diperbarui.
Bagaimanapun, apa yang biasanya saya sukai adalah salah satu metode yang memungkinkan saya mengganti semua item RecyclerViewsekaligus. Hapus semua yang tidak ada dalam Listdan tambahkan semua item yang hilang dari SortedList:
public void replaceAll(List<ExampleModel> models) {
mSortedList.beginBatchedUpdates();
for (int i = mSortedList.size() - 1; i >= 0; i--) {
final ExampleModel model = mSortedList.get(i);
if (!models.contains(model)) {
mSortedList.remove(model);
}
}
mSortedList.addAll(models);
mSortedList.endBatchedUpdates();
}
Metode ini sekali lagi mengelompokkan semua pembaruan bersama untuk meningkatkan kinerja. Loop pertama terbalik karena menghapus item di awal akan mengacaukan indeks semua item yang muncul setelahnya dan ini dapat menyebabkan beberapa kasus masalah seperti inkonsistensi data. Setelah itu kita tambahkan saja Listke SortedListmenggunakan addAll()untuk menambahkan semua item yang belum ada di SortedListdan - sama seperti yang saya jelaskan di atas - perbarui semua item yang sudah ada di SortedListtetapi telah berubah.
Dan dengan itu Adapterselesai. Semuanya akan terlihat seperti ini:
public class ExampleAdapter extends RecyclerView.Adapter<ExampleViewHolder> {
private final SortedList<ExampleModel> mSortedList = new SortedList<>(ExampleModel.class, new SortedList.Callback<ExampleModel>() {
@Override
public int compare(ExampleModel a, ExampleModel b) {
return mComparator.compare(a, b);
}
@Override
public void onInserted(int position, int count) {
notifyItemRangeInserted(position, count);
}
@Override
public void onRemoved(int position, int count) {
notifyItemRangeRemoved(position, count);
}
@Override
public void onMoved(int fromPosition, int toPosition) {
notifyItemMoved(fromPosition, toPosition);
}
@Override
public void onChanged(int position, int count) {
notifyItemRangeChanged(position, count);
}
@Override
public boolean areContentsTheSame(ExampleModel oldItem, ExampleModel newItem) {
return oldItem.equals(newItem);
}
@Override
public boolean areItemsTheSame(ExampleModel item1, ExampleModel item2) {
return item1 == item2;
}
});
private final Comparator<ExampleModel> mComparator;
private final LayoutInflater mInflater;
public ExampleAdapter(Context context, Comparator<ExampleModel> comparator) {
mInflater = LayoutInflater.from(context);
mComparator = comparator;
}
@Override
public ExampleViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
final ItemExampleBinding binding = ItemExampleBinding.inflate(mInflater, parent, false);
return new ExampleViewHolder(binding);
}
@Override
public void onBindViewHolder(ExampleViewHolder holder, int position) {
final ExampleModel model = mSortedList.get(position);
holder.bind(model);
}
public void add(ExampleModel model) {
mSortedList.add(model);
}
public void remove(ExampleModel model) {
mSortedList.remove(model);
}
public void add(List<ExampleModel> models) {
mSortedList.addAll(models);
}
public void remove(List<ExampleModel> models) {
mSortedList.beginBatchedUpdates();
for (ExampleModel model : models) {
mSortedList.remove(model);
}
mSortedList.endBatchedUpdates();
}
public void replaceAll(List<ExampleModel> models) {
mSortedList.beginBatchedUpdates();
for (int i = mSortedList.size() - 1; i >= 0; i--) {
final ExampleModel model = mSortedList.get(i);
if (!models.contains(model)) {
mSortedList.remove(model);
}
}
mSortedList.addAll(models);
mSortedList.endBatchedUpdates();
}
@Override
public int getItemCount() {
return mSortedList.size();
}
}
Satu-satunya hal yang hilang sekarang adalah menerapkan pemfilteran!
Menerapkan logika filter
Untuk mengimplementasikan logika filter, pertama-tama kita harus mendefinisikan Listsemua model yang mungkin. Untuk contoh ini saya membuat Listdari ExampleModelcontoh dari array film:
private static final String[] MOVIES = new String[]{
...
};
private static final Comparator<ExampleModel> ALPHABETICAL_COMPARATOR = new Comparator<ExampleModel>() {
@Override
public int compare(ExampleModel a, ExampleModel b) {
return a.getText().compareTo(b.getText());
}
};
private ExampleAdapter mAdapter;
private List<ExampleModel> mModels;
private RecyclerView mRecyclerView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);
mAdapter = new ExampleAdapter(this, ALPHABETICAL_COMPARATOR);
mBinding.recyclerView.setLayoutManager(new LinearLayoutManager(this));
mBinding.recyclerView.setAdapter(mAdapter);
mModels = new ArrayList<>();
for (String movie : MOVIES) {
mModels.add(new ExampleModel(movie));
}
mAdapter.add(mModels);
}
Tidak ada yang istimewa terjadi di sini, kami hanya instantiate Adapterdan set ke RecyclerView. Setelah itu kami membuat Listmodel dari nama-nama film dalam MOVIESarray. Kemudian kami menambahkan semua model ke SortedList.
Sekarang kita dapat kembali ke onQueryTextChange()yang telah kita tentukan sebelumnya dan mulai menerapkan logika filter:
@Override
public boolean onQueryTextChange(String query) {
final List<ExampleModel> filteredModelList = filter(mModels, query);
mAdapter.replaceAll(filteredModelList);
mBinding.recyclerView.scrollToPosition(0);
return true;
}
Ini lagi cukup lurus ke depan. Kami memanggil metode filter()dan meneruskan Listdari ExampleModels serta string kueri. Kami kemudian memanggil replaceAll()pada Adapterdan lulus dalam disaring Listkembali oleh filter(). Kami juga harus memanggil scrollToPosition(0)pada RecyclerViewuntuk memastikan bahwa pengguna dapat selalu melihat semua item saat mencari sesuatu. Kalau tidak, RecyclerViewmungkin tetap dalam posisi digulir ke bawah saat penyaringan dan kemudian menyembunyikan beberapa item. Menggulir ke atas memastikan pengalaman pengguna yang lebih baik saat mencari.
Satu-satunya yang tersisa untuk dilakukan sekarang adalah mengimplementasikannya filter()sendiri:
private static List<ExampleModel> filter(List<ExampleModel> models, String query) {
final String lowerCaseQuery = query.toLowerCase();
final List<ExampleModel> filteredModelList = new ArrayList<>();
for (ExampleModel model : models) {
final String text = model.getText().toLowerCase();
if (text.contains(lowerCaseQuery)) {
filteredModelList.add(model);
}
}
return filteredModelList;
}
Hal pertama yang kami lakukan di sini adalah memanggil toLowerCase()string kueri. Kami tidak ingin fungsi pencarian kami peka huruf besar kecil dan dengan memanggil toLowerCase()semua string yang kami bandingkan kami dapat memastikan bahwa kami mengembalikan hasil yang sama terlepas dari huruf besar-kecil. Itu kemudian hanya mengulangi semua model di Listkita melewati ke dalamnya dan memeriksa apakah string kueri terkandung dalam teks model. Jika ya maka model ditambahkan ke filter List.
Dan itu dia! Kode di atas akan berjalan pada API level 7 dan di atas dan dimulai dengan API level 11 Anda mendapatkan animasi item gratis!
Saya menyadari bahwa ini adalah deskripsi yang sangat terperinci yang mungkin membuat semua ini tampak lebih rumit daripada yang sebenarnya, tetapi ada cara kita dapat menggeneralisasi seluruh masalah ini dan membuat implementasi Adapterberbasis pada yang SortedListlebih sederhana.
Menyamaratakan masalah dan menyederhanakan Adaptor
Pada bagian ini saya tidak akan membahas banyak detail - sebagian karena saya berlari melawan batas karakter untuk jawaban pada Stack Overflow tetapi juga karena sebagian besar sudah dijelaskan di atas - tetapi untuk meringkas perubahan: Kita dapat menerapkan Adapterkelas dasar yang sudah menangani berurusan dengan SortedListserta model mengikat untuk ViewHoldercontoh dan menyediakan cara yang nyaman untuk mengimplementasikan Adapterberbasis pada a SortedList. Untuk itu kita harus melakukan dua hal:
- Kita perlu membuat
ViewModelantarmuka yang harus diimplementasikan oleh semua kelas model
- Kita perlu membuat
ViewHoldersubclass yang mendefinisikan bind()metode yang Adapterdapat digunakan untuk mengikat model secara otomatis.
Hal ini memungkinkan kami untuk hanya fokus pada konten yang seharusnya ditampilkan di RecyclerViewhanya dengan mengimplementasikan model dan ada ViewHolderimplementasi yang sesuai . Menggunakan kelas dasar ini kita tidak perlu khawatir tentang detail rumit dari Adapterdan SortedList.
DiurutkanDaftarAdapter
Karena batas karakter untuk jawaban di StackOverflow, saya tidak bisa melalui setiap langkah menerapkan kelas dasar ini atau bahkan menambahkan kode sumber lengkap di sini, tetapi Anda dapat menemukan kode sumber lengkap dari kelas dasar ini - saya menyebutnya SortedListAdapter- dalam hal ini GitHub Gist .
Untuk mempermudah hidup Anda, saya telah menerbitkan perpustakaan di jCenter yang berisi SortedListAdapter! Jika Anda ingin menggunakannya maka yang perlu Anda lakukan adalah menambahkan dependensi ini ke file build.gradle aplikasi Anda:
compile 'com.github.wrdlbrnft:sorted-list-adapter:0.2.0.1'
Anda dapat menemukan informasi lebih lanjut tentang perpustakaan ini di beranda perpustakaan .
Menggunakan SortedListAdapter
Untuk menggunakan SortedListAdapter kita harus membuat dua perubahan:
Ubah ViewHoldersehingga memanjang SortedListAdapter.ViewHolder. Parameter tipe harus menjadi model yang harus terikat pada ini ViewHolder- dalam hal ini ExampleModel. Anda harus mengikat data ke model Anda performBind()sebagai ganti bind().
public class ExampleViewHolder extends SortedListAdapter.ViewHolder<ExampleModel> {
private final ItemExampleBinding mBinding;
public ExampleViewHolder(ItemExampleBinding binding) {
super(binding.getRoot());
mBinding = binding;
}
@Override
protected void performBind(ExampleModel item) {
mBinding.setModel(item);
}
}
Pastikan semua model Anda menerapkan ViewModelantarmuka:
public class ExampleModel implements SortedListAdapter.ViewModel {
...
}
Setelah itu kita hanya perlu memperbarui ExampleAdapteruntuk memperpanjang SortedListAdapterdan menghapus semua yang tidak kita butuhkan lagi. Parameter tipe harus tipe model yang Anda kerjakan - dalam hal ini ExampleModel. Tetapi jika Anda bekerja dengan berbagai jenis model maka atur parameter type ke ViewModel.
public class ExampleAdapter extends SortedListAdapter<ExampleModel> {
public ExampleAdapter(Context context, Comparator<ExampleModel> comparator) {
super(context, ExampleModel.class, comparator);
}
@Override
protected ViewHolder<? extends ExampleModel> onCreateViewHolder(LayoutInflater inflater, ViewGroup parent, int viewType) {
final ItemExampleBinding binding = ItemExampleBinding.inflate(inflater, parent, false);
return new ExampleViewHolder(binding);
}
@Override
protected boolean areItemsTheSame(ExampleModel item1, ExampleModel item2) {
return item1.getId() == item2.getId();
}
@Override
protected boolean areItemContentsTheSame(ExampleModel oldItem, ExampleModel newItem) {
return oldItem.equals(newItem);
}
}
Setelah itu kita selesai! Namun satu hal lagi yang disebutkan: Tidak SortedListAdapterada yang sama add(), remove()atau replaceAll()metode yang asli kami ExampleAdaptermiliki. Ini menggunakan Editorobjek terpisah untuk memodifikasi item dalam daftar yang dapat diakses melalui edit()metode ini. Jadi, jika Anda ingin menghapus atau menambahkan item yang harus Anda panggil edit()kemudian tambahkan dan hapus item pada Editorcontoh ini dan setelah Anda selesai, panggil commit()itu untuk menerapkan perubahan pada SortedList:
mAdapter.edit()
.remove(modelToRemove)
.add(listOfModelsToAdd)
.commit();
Semua perubahan yang Anda lakukan dengan cara ini dikumpulkan bersama untuk meningkatkan kinerja. The replaceAll()Metode kami menerapkan dalam bab-bab di atas juga hadir pada ini Editorobjek:
mAdapter.edit()
.replaceAll(mModels)
.commit();
Jika Anda lupa menelepon, commit()maka perubahan Anda tidak akan diterapkan!