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/menu
yeni bir dosya oluşturun main_menu.xml
. İçinde bir öğe eklemek ve set actionViewClass
iç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 Fragment
ya da Activity
her zamanki gibi bu menüyü xml şişirmek zorundaysanız, o zaman MenuItem
hangisini içerdiğini arayabilir SearchView
ve OnQueryTextListener
iç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 SearchView
kullanı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 ViewHolder
için ExampleModel
sı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 Adapter
ve bunun yerine bu cevap için ilgili bölümlere konsantre olacağım.
Ama önce konuşmamız gereken bir şey var: SortedList
Sınıf.
SortedList
SortedList
Bir parçası olan tamamen şaşırtıcı bir araçtır RecyclerView
kütüphanede. Adapter
Veri 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()
, SortedList
a'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 SortedList
gereken Adapter
bir Callback
sı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
, onInserted
vb Eşdeğer aramalarınızdan yöntemini bildirmek aramak zorunda Adapter
. Üç altındaki yöntemleri compare
, areContentsTheSame
ve areItemsTheSame
bu 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 Comparator
iki 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ı List
ve 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.Callback
doğ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 SortedList
modellerinizin sınıfını geçmeniz gerekir. Diğer parametre sadece SortedList.Callback
yukarıda tanımladığımızdır.
Şimdi işe başlayalım: Eğer Adapter
bir 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();
}
}
Comparator
Aynı 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ü SortedList
zaten bunu SortedList.Callback
! Bunun yanı sıra, bu yöntemlerin uygulanması bir istisna dışında oldukça basittir: bir List
modeli kaldıran kaldır yöntemi . Yana SortedList
biz 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 SortedList
birlikte 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 SortedList
ve zaten içinde bulunuyorsa, SortedList
tekrar eklenmeyecektir. Bunun yerine, nesnenin değişip değişmediğini ve öğede öğenin olup olmadığını anlamak SortedList
için areContentsTheSame()
yöntemi kullanır RecyclerView
.
Her neyse, genellikle tercih ettiğim, bir RecyclerView
kerede tüm öğeleri değiştirmeme izin veren bir yöntemdir . İçinde olmayan her şeyi kaldırın List
ve 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 List
için SortedList
kullanma addAll()
henüz bulunmayan tüm öğeler eklemek için SortedList
ve - yukarıda açıklanan gibi - güncelleme zaten tüm öğeleri SortedList
ama değişti.
Ve bununla birlikte Adapter
tamamlandı. 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 List
olası tüm modellerden birini tanımlamamız gerekir . Bu örnek için ben oluşturmak List
ait ExampleModel
filmlerin 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 Adapter
ve RecyclerView
. Bundan sonra dizideki List
film 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 List
arasında ExampleModel
iyi sorgu dizesi gibi s. Sonra diyoruz replaceAll()
üzerinde Adapter
ve filtrelenmiş geçmek List
tarafından döndürülen filter()
. Ayrıca aramak zorunda scrollToPosition(0)
üzerine RecyclerView
bir şeyler ararken kullanıcı her zaman tüm öğeleri görebilirsiniz sağlamak için. Aksi takdirde, RecyclerView
filtreleme 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, List
iç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 Adapter
bir 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 Adapter
sınıf uygulayabiliriz zaten örneklerle SortedList
bağlamanın yanı sıra modellerle başa çıkmaya özen gösterir ViewHolder
ve Adapter
a SortedList
. Bunun için iki şey yapmalıyız:
ViewModel
Tü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
ViewHolder
bir bind()
yöntemi tanımlayan bir alt sınıf yaratmamız gerekir Adapter
.
Bu, sadece RecyclerView
modelleri uygulayarak ve karşılık gelen ViewHolder
uygulamaları 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 Adapter
ve 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 SortedListAdapter
için iki değişiklik yapmalıyız:
Değişim ViewHolder
o 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 ViewModel
arayüzü uyguladığından emin olun :
public class ExampleModel implements SortedListAdapter.ViewModel {
...
}
Bundan sonra, artık ihtiyacımız olmayan her şeyi ExampleAdapter
genişletmek SortedListAdapter
ve 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: SortedListAdapter
Aynı yoktur add()
, remove()
ya replaceAll()
orijinal yöntemleri ExampleAdapter
vardı. Editor
Listedeki 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 Editor
bir nesne:
mAdapter.edit()
.replaceAll(mModels)
.commit();
Telefon etmeyi unutursanız commit()
, değişikliklerinizin hiçbiri uygulanmaz!