Отфильтруйте RealmResults с помощью запроса String и получите детальные анимации RecyclerView
Я хочу отфильтровать список на основе RealmRecyclerViewAdapter
и получить гранулированные анимации (notifyItemRange*()
).
Моя логика фильтрации:
override fun observeCampaigns(nameQuery: String): Flowable<RealmResults<CampaignRealm>> =
Realm.getDefaultInstance().use { realm ->
realm.where<CampaignRealm>()
.contains(CampaignRealmFields.NAME, nameQuery, Case.INSENSITIVE)
.findAllAsync()
.asFlowable()
.filter { it.isLoaded }
}
Проблема в том, что внутри адаптера состояние changeSet всегда НАЧАЛЬНОЕ, я предполагаю, потому что я создаю новый объект RealmResults каждый раз, когда я меняю запрос.
private OrderedRealmCollectionChangeListener createListener() {
return new OrderedRealmCollectionChangeListener() {
@Override
public void onChange(Object collection, OrderedCollectionChangeSet changeSet) {
if (changeSet.getState() == OrderedCollectionChangeSet.State.INITIAL) {
// IT ALWAYS HITS THIS
notifyDataSetChanged();
return;
}
// For deletions, the adapter has to be notified in reverse order.
OrderedCollectionChangeSet.Range[] deletions = changeSet.getDeletionRanges();
for (int i = deletions.length - 1; i >= 0; i--) {
OrderedCollectionChangeSet.Range range = deletions[i];
notifyItemRangeRemoved(range.startIndex, range.length);
}
OrderedCollectionChangeSet.Range[] insertions = changeSet.getInsertionRanges();
for (OrderedCollectionChangeSet.Range range : insertions) {
notifyItemRangeInserted(range.startIndex, range.length);
}
if (!updateOnModification) {
return;
}
OrderedCollectionChangeSet.Range[] modifications = changeSet.getChangeRanges();
for (OrderedCollectionChangeSet.Range range : modifications) {
notifyItemRangeChanged(range.startIndex, range.length);
}
}
};
}
Я не мог найти решение нигде. Я не могу быть первым человеком, у которого есть простой случай использования как это... правильно?! (Я схожу с ума здесь)
Идеи?
1 ответ
Вы можете сделать что-то вроде этого: его работа для меня, чтобы получить обновленный результат с фильтром и уведомить ваш адаптер. и другое решение см. этот код
@Override
public Flowable<RealmResults<Campaigns>> searchCampaigns(String nameQuery) {
try (Realm realm = Realm.getDefaultInstance()) {
RealmQuery<Campaigns> query = realm.where(Campaigns.class)
.contains(CampaignRealmFields.NAME, nameQuery, Case.INSENSITIVE)
return query
.findAllAsync()
.asFlowable()
.onBackpressureLatest()
.toObservable()
.flatMap(realmResultsCollectionChange ->
query.findAllAsync().asChangesetObservable());
}
}
searchCampaigns(something).subscribe(new Observer<CollectionChange<RealmResults<Campaigns>>>() {
@Override
public void onSubscribe(Disposable d) {
compositeDisposable.add(d);
}
@Override
public void onNext(CollectionChange<RealmResults<Campaigns>> realmResultsCollectionChange) {
ticketRealmResults=realmResultsCollectionChange.getCollection();
if (realmResultsCollectionChange.getChangeset().getChangeRanges().length > 1) {
OrderedCollectionChangeSet.Range[] changerange = realmResultsCollectionChange.getChangeset().getChangeRanges();
for (int i = changerange.length - 1; i >= 0; i--) {
OrderedCollectionChangeSet.Range range = changerange[i];
notifyItemRangeRemoved(range.startIndex, range.length);
}
}
if (realmResultsCollectionChange.getChangeset().getDeletionRanges().length > 0) {
OrderedCollectionChangeSet.Range[] deletionRanges = realmResultsCollectionChange.getChangeset().getDeletionRanges();
for (int i = deletionRanges.length - 1; i >= 0; i--) {
OrderedCollectionChangeSet.Range range = deletionRanges[i];
notifyItemRangeRemoved(range.startIndex, range.length);
}
}
if (realmResultsCollectionChange.getChangeset().getInsertionRanges().length > 0) {
OrderedCollectionChangeSet.Range[] InsertionRanges = realmResultsCollectionChange.getChangeset().getInsertionRanges();
for (int i = InsertionRanges.length - 1; i >= 0; i--) {
OrderedCollectionChangeSet.Range range = InsertionRanges[i];
notifyItemRangeRemoved(range.startIndex, range.length);
}
}
}
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
});