Giriş
Sorunuzla tam olarak neyle ilgili sorun yaşadığınız tam olarak açık olmadığından, bu özelliğin nasıl uygulanacağı ile ilgili bu kısa yolu yazdım; eğer hala sorularınız varsa sormaya çekinmeyin.
Bu GitHub Deposunda burada bahsettiğim her şeyin çalışma örneği var .
Örnek proje hakkında daha fazla bilgi edinmek isterseniz proje ana sayfasını ziyaret edin .
Her durumda sonuç şöyle görünmelidir:

Demo uygulamasıyla ilk önce oynamak istiyorsanız Play Store'dan yükleyebilirsiniz:

Neyse başlayalım.
Kurulum SearchView
Klasörde res/menuyeni bir dosya oluşturun main_menu.xml. İçinde bir öğe eklemek ve set actionViewClassiçin android.support.v7.widget.SearchView. Destek kitaplığını kullandığınız için, actionViewClassözelliği ayarlamak için destek kitaplığının ad alanını kullanmanız gerekir . Xml dosyanızın şöyle görünmesi gerekir:
<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>
Sizin Fragmentya da Activityher zamanki gibi bu menüyü xml şişirmek zorundaysanız, o zaman MenuItemhangisini içerdiğini arayabilir SearchViewve OnQueryTextListeneriçine girilen metindeki değişiklikleri dinlemek için kullanacağımız uygulamayı uygulayabilirsiniz 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;
}
Ve şimdi SearchViewkullanılmaya hazır. Filtre mantığını daha sonra onQueryTextChange()uygulamayı bitirdikten sonra uygulayacağız Adapter.
Kurulum Adapter
İlk ve en önemlisi, bu örnek için kullanacağım model sınıfı:
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;
}
}
Bir metni görüntüleyecek olan sadece temel modeliniz RecyclerView. Bu metni görüntülemek için kullanacağım düzen:
<?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>
Gördüğünüz gibi Veri Bağlama kullanıyorum. Daha önce hiç veri bağlama ile çalışmadıysanız cesaretiniz kırılmasın! Çok basit ve güçlü, ancak bu cevap kapsamında nasıl çalıştığını açıklayamıyorum.
Bu ViewHolderiçin ExampleModelsınıfın:
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);
}
}
Yine özel bir şey yok. Sadece yukarıdaki xml düzeninde tanımladığımız gibi model sınıfını bu düzene bağlamak için veri bağlama kullanır.
Şimdi nihayet gerçekten ilginç kısma gelebiliriz: Adaptörün Yazılması. Ben temel uygulaması atlayacağım Adapterve bunun yerine bu cevap için ilgili bölümlere konsantre olacağım.
Ama önce konuşmamız gereken bir şey var: SortedListSınıf.
SortedList
SortedListBir parçası olan tamamen şaşırtıcı bir araçtır RecyclerViewkütüphanede. AdapterVeri setindeki değişiklikleri bildirmeye özen gösterir ve bunu çok verimli bir şekilde yapar. Yapmanız gereken tek şey öğelerin sırasını belirtmektir. Bunu compare(), SortedLista'daki gibi iki öğeyi karşılaştıran bir yöntem uygulayarak yapmanız gerekir Comparator. Ama sıralamak yerine List, öğeleri sıralamak için kullanılır RecyclerView!
Uygulamanız SortedListgereken Adapterbir Callbacksınıf aracılığıyla etkileşime girer :
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();
}
}
Gibi callback'inde üstündeki yöntemlerinde onMoved, onInsertedvb Eşdeğer aramalarınızdan yöntemini bildirmek aramak zorunda Adapter. Üç altındaki yöntemleri compare, areContentsTheSameve areItemsTheSamebu nesneler ekranda görünmelidir sipariş ne tür nesnelerin görüntülemek istediğiniz ne ve ya uygun uygulamak zorunda.
Bu yöntemleri tek tek inceleyelim:
@Override
public int compare(ExampleModel a, ExampleModel b) {
return mComparator.compare(a, b);
}
Bu compare()daha önce konuştuğumuz yöntemi. Bu örnekte sadece Comparatoriki modeli karşılaştıran bir çağrıya geçiyorum . Öğelerin ekranda alfabetik sırada görünmesini istiyorsanız. Bu karşılaştırıcı şöyle görünebilir:
private static final Comparator<ExampleModel> ALPHABETICAL_COMPARATOR = new Comparator<ExampleModel>() {
@Override
public int compare(ExampleModel a, ExampleModel b) {
return a.getText().compareTo(b.getText());
}
};
Şimdi bir sonraki yönteme bakalım:
@Override
public boolean areContentsTheSame(ExampleModel oldItem, ExampleModel newItem) {
return oldItem.equals(newItem);
}
Bu yöntemin amacı, bir modelin içeriğinin değişip değişmediğini belirlemektir. Bunu SortedList, bir değişiklik olayının başlatılması gerekip gerekmediğini belirlemek için kullanır; başka bir deyişle RecyclerView, eski ve yeni sürümü crossfade etmelidir. Eğer sınıfları doğru equals()ve hashCode()uygulamanız varsa, genellikle yukarıdaki gibi uygulayabilirsiniz. Sınıfa bir equals()ve hashCode()uygulama eklersek ExampleModel, şöyle görünmelidir:
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;
}
}
Hızlı yan not: Android Studio, IntelliJ ve Eclipse gibi çoğu IDE , bir düğmeye basarak sizin için oluşturma equals()ve hashCode()uygulama işlevlerine sahiptir ! Yani onları kendiniz uygulamak zorunda değilsiniz. İnternette IDE'nizde nasıl çalıştığını görün!
Şimdi son yönteme bir göz atalım:
@Override
public boolean areItemsTheSame(ExampleModel item1, ExampleModel item2) {
return item1.getId() == item2.getId();
}
SortedListÖğenin aynı şeyi gösterirler olmadığını kontrol için bu yöntemi kullanır. En basit ifadeyle (nasıl SortedListçalıştığını açıklamadan ) bu, bir nesnenin zaten içerilmiş olup olmadığını Listve bir ekleme, taşıma veya değiştirme animasyonunun oynatılması gerekip gerekmediğini belirlemek için kullanılır . Modellerinizin bir kimliği varsa, genellikle bu yöntemdeki kimliği karşılaştırabilirsiniz. Eğer yapmazlarsa, bunu kontrol etmenin başka bir yolunu bulmanız gerekir, ancak bunu uygulamanız sonuç olarak uygulamanıza bağlıdır. Genellikle tüm modellere bir kimlik vermek en basit seçenektir - örneğin, bir veritabanındaki verileri sorguluyorsanız birincil anahtar alanı olabilir.
İle SortedList.Callbackdoğru bir şekilde uygulandığında biz bir örneğini oluşturabilir SortedList:
final SortedList<ExampleModel> list = new SortedList<>(ExampleModel.class, mCallback);
Yapıcıdaki ilk parametre olarak SortedListmodellerinizin sınıfını geçmeniz gerekir. Diğer parametre sadece SortedList.Callbackyukarıda tanımladığımızdır.
Şimdi işe başlayalım: Eğer Adapterbir ile uygularsak SortedListşöyle bir şey olmalı:
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();
}
}
ComparatorAynı kullanabilmesi madde yapıcı içinden geçirilir sıralamak için kullanılan Adapteröğeler farklı bir sırada görüntülenecek gerekiyordu bile.
Şimdi neredeyse bitti! Ancak, önce öğeye öğe eklemek veya kaldırmak için bir yola ihtiyacımız var Adapter. Bu amaçla, aşağıdakilere Adapteröğe eklememize ve kaldırmamıza izin veren yöntemler ekleyebiliriz 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();
}
Burada herhangi bir bildirim yöntemini çağırmamız gerekmez, çünkü SortedListzaten bunu SortedList.Callback! Bunun yanı sıra, bu yöntemlerin uygulanması bir istisna dışında oldukça basittir: bir Listmodeli kaldıran kaldır yöntemi . Yana SortedListbiz liste üzerinde döngü gereken tek bir nesneyi kaldırmak ve tek modeller birini kaldırmak edebilecek tek kaldır yöntemi vardır. Arayan beginBatchedUpdates()biz yapacağız başlayan toplu Tüm değişikliklere SortedListbirlikte ile ve performansı artırır. Dediğimiz zaman bir kerede tüm değişiklikler hakkında bilgilendirilir.endBatchedUpdates()RecyclerView
Ek olarak, anlamanız gereken şey, içine bir nesne eklerseniz SortedListve zaten içinde bulunuyorsa, SortedListtekrar eklenmeyecektir. Bunun yerine, nesnenin değişip değişmediğini ve öğede öğenin olup olmadığını anlamak SortedListiçin areContentsTheSame()yöntemi kullanır RecyclerView.
Her neyse, genellikle tercih ettiğim, bir RecyclerViewkerede tüm öğeleri değiştirmeme izin veren bir yöntemdir . İçinde olmayan her şeyi kaldırın Listve eksik olan tüm öğeleri ekleyin 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();
}
Bu yöntem, performansı artırmak için tüm güncelleştirmeleri toplu olarak bir araya getirir. İlk döngü, başlangıçta bir öğeyi kaldırmak, ondan sonra gelen tüm öğelerin dizinlerini bozacağından ve bazı durumlarda veri tutarsızlıkları gibi sorunlara yol açabileceğinden tersidir. Sonra biz sadece eklemek Listiçin SortedListkullanma addAll()henüz bulunmayan tüm öğeler eklemek için SortedListve - yukarıda açıklanan gibi - güncelleme zaten tüm öğeleri SortedListama değişti.
Ve bununla birlikte Adaptertamamlandı. Her şey şöyle görünmelidir:
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();
}
}
Şimdi eksik olan tek şey filtrelemeyi uygulamak!
Filtre mantığını uygulama
Filtre mantığını uygulamak için önce Listolası tüm modellerden birini tanımlamamız gerekir . Bu örnek için ben oluşturmak Listait ExampleModelfilmlerin bir diziden durumlarda:
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);
}
Burada özel bir şey yok, biz sadece somutlaştırıyoruz Adapterve RecyclerView. Bundan sonra dizideki Listfilm adlarından bir model oluşturuyoruz MOVIES. Sonra tüm modelleri SortedList.
Şimdi onQueryTextChange()daha önce tanımladığımız geri dönebilir ve filtre mantığını uygulamaya başlayabiliriz:
@Override
public boolean onQueryTextChange(String query) {
final List<ExampleModel> filteredModelList = filter(mModels, query);
mAdapter.replaceAll(filteredModelList);
mBinding.recyclerView.scrollToPosition(0);
return true;
}
Bu yine oldukça basit. Biz yöntemini çağırın filter()ve geçmek Listarasında ExampleModeliyi sorgu dizesi gibi s. Sonra diyoruz replaceAll()üzerinde Adapterve filtrelenmiş geçmek Listtarafından döndürülen filter(). Ayrıca aramak zorunda scrollToPosition(0)üzerine RecyclerViewbir şeyler ararken kullanıcı her zaman tüm öğeleri görebilirsiniz sağlamak için. Aksi takdirde, RecyclerViewfiltreleme sırasında aşağı kaydırılmış konumda kalabilir ve daha sonra birkaç öğeyi gizleyebilir. En üste kaydırmak arama yaparken daha iyi bir kullanıcı deneyimi sağlar.
Şimdi geriye kalan tek şey filter()kendini uygulamaktır :
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;
}
Burada yaptığımız ilk şey toLowerCase(), sorgu dizesine çağrı yapmaktır . Arama fonksiyonumuzun büyük / küçük harfe duyarlı olmasını istemiyoruz ve toLowerCase()karşılaştırdığımız tüm dizeleri çağırarak , durumdan bağımsız olarak aynı sonuçları döndürmemizi sağlayabiliriz. Daha sonra, Listiçine geçirdiğimiz tüm modeller arasında yinelenir ve sorgu dizesinin model metninde olup olmadığını kontrol eder. Eğer öyleyse, model filtreye eklenir List.
Ve bu kadar! Yukarıdaki kod API seviye 7 ve üstünde çalışır ve API seviye 11 ile başlayarak ücretsiz olarak öğe animasyonları alırsınız!
Bunun çok ayrıntılı bir açıklama olduğunu anlıyorum, bu muhtemelen her şeyi olduğundan daha karmaşık görünüyor, ancak tüm sorunu genelleştirebilmemizi ve uygulamayı çok daha basit Adapterbir temelde yapmanın bir yolu var SortedList.
Sorunu genelleme ve Bağdaştırıcıyı basitleştirme
Bu bölümde fazla ayrıntıya girmeyeceğim - kısmen Stack Overflow'daki cevaplar için karakter sınırına karşı koştuğum için değil, aynı zamanda çoğu yukarıda açıklandığı için - ama değişiklikleri özetlemek için: Bir temel Adaptersınıf uygulayabiliriz zaten örneklerle SortedListbağlamanın yanı sıra modellerle başa çıkmaya özen gösterir ViewHolderve Adaptera SortedList. Bunun için iki şey yapmalıyız:
ViewModelTüm model sınıflarının uygulamak zorunda olduğu bir arayüz oluşturmamız gerekiyor
- Modelleri otomatik olarak bağlamak için kullanabileceğiniz
ViewHolderbir bind()yöntemi tanımlayan bir alt sınıf yaratmamız gerekir Adapter.
Bu, sadece RecyclerViewmodelleri uygulayarak ve karşılık gelen ViewHolderuygulamaları uygulayarak görüntülenmesi gereken içeriğe odaklanmamızı sağlar . Bu temel sınıf kullanma biz karmaşık detayları hakkında endişe gerekmez Adapterve onun SortedList.
SortedListAdapter
Çünkü bu temel sınıf uygulayan ve hatta burada tam kaynak kodu ekleyin, ancak bu temel sınıf tam kaynak kodu bulabilirsiniz her bir adımına devam edemez StackOverflow I cevapları için karakter sınırı - Ben denilen SortedListAdapter- bunda GitHub Gist .
Hayatınızı kolaylaştırmak için jCenter'da içeren bir kütüphane yayınladım SortedListAdapter! Kullanmak istiyorsanız, yapmanız gereken tek şey bu bağımlılığı uygulamanızın build.gradle dosyasına eklemektir:
compile 'com.github.wrdlbrnft:sorted-list-adapter:0.2.0.1'
Bu kütüphane hakkında daha fazla bilgiyi kütüphane ana sayfasında bulabilirsiniz .
SortedListAdapter kullanma
Kullanmak SortedListAdapteriçin iki değişiklik yapmalıyız:
Değişim ViewHoldero uzanacak şekilde SortedListAdapter.ViewHolder. Type parametresi, buna bağlı olması gereken model olmalıdır ViewHolder- bu durumda ExampleModel. Bunun performBind()yerine verileri modellerinize bağlamak zorundasınız 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);
}
}
Tüm modellerinizin ViewModelarayüzü uyguladığından emin olun :
public class ExampleModel implements SortedListAdapter.ViewModel {
...
}
Bundan sonra, artık ihtiyacımız olmayan her şeyi ExampleAdaptergenişletmek SortedListAdapterve kaldırmak için güncellememiz gerekiyor. Type parametresi, birlikte çalıştığınız model türü olmalıdır - bu durumda ExampleModel. Ancak farklı modellerle çalışıyorsanız, type parametresini olarak ayarlayın 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);
}
}
Ondan sonra işimiz bitti! Söz etmek Ancak son bir şey: SortedListAdapterAynı yoktur add(), remove()ya replaceAll()orijinal yöntemleri ExampleAdaptervardı. EditorListedeki yöntemle erişilebilen öğeleri değiştirmek için ayrı bir nesne kullanır edit(). Bu nedenle, çağırmanız gereken öğeleri kaldırmak veya eklemek istiyorsanız edit(), bu Editorörneğe öğeleri ekleyin ve kaldırın ve işiniz bittiğinde, commit()değişiklikleri aşağıdakilere uygulamak için çağırın SortedList:
mAdapter.edit()
.remove(modelToRemove)
.add(listOfModelsToAdd)
.commit();
Bu şekilde yaptığınız tüm değişiklikler performansı artırmak için bir araya getirilir. replaceAll()Yukarıdaki bölümlerde uygulanan yöntem, aynı zamanda, bu üzerinde mevcut olan Editorbir nesne:
mAdapter.edit()
.replaceAll(mModels)
.commit();
Telefon etmeyi unutursanız commit(), değişikliklerinizin hiçbiri uygulanmaz!