diff --git a/src/main/java/ru/touchin/roboswag/core/observables/collections/ObservableCollection.java b/src/main/java/ru/touchin/roboswag/core/observables/collections/ObservableCollection.java index be43762..527a905 100644 --- a/src/main/java/ru/touchin/roboswag/core/observables/collections/ObservableCollection.java +++ b/src/main/java/ru/touchin/roboswag/core/observables/collections/ObservableCollection.java @@ -23,6 +23,7 @@ import android.support.annotation.NonNull; import java.util.ArrayList; import java.util.List; +import java.util.concurrent.TimeUnit; import rx.Observable; import rx.internal.util.RxRingBuffer; @@ -34,6 +35,8 @@ import rx.subjects.PublishSubject; */ public abstract class ObservableCollection { + private static final long MIN_TIME_BEFORE_UPDATES = 100; + @NonNull private final PublishSubject changeSubject = PublishSubject.create(); @@ -41,9 +44,15 @@ public abstract class ObservableCollection { changeSubject.onNext(change); } + protected void notifyAboutChanges(@NonNull final List changes) { + for (final Change change : changes) { + changeSubject.onNext(change); + } + } + @NonNull - public Observable observeChanges() { - return changeSubject; + public Observable> observeChanges() { + return changeSubject.buffer(MIN_TIME_BEFORE_UPDATES, TimeUnit.MILLISECONDS); } public abstract int size(); diff --git a/src/main/java/ru/touchin/roboswag/core/observables/collections/ObservableFilteredList.java b/src/main/java/ru/touchin/roboswag/core/observables/collections/ObservableFilteredList.java new file mode 100644 index 0000000..8739402 --- /dev/null +++ b/src/main/java/ru/touchin/roboswag/core/observables/collections/ObservableFilteredList.java @@ -0,0 +1,76 @@ +package ru.touchin.roboswag.core.observables.collections; + +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import rx.Observable; +import rx.functions.Func1; + +/** + * Created by Gavriil Sitnikov on 02/06/2016. + * TODO: fill description + */ +public class ObservableFilteredList extends ObservableCollection { + + @NonNull + private static Collection filterCollection(@NonNull final Collection sourceCollection, + @NonNull final Func1 filter) { + final List result = new ArrayList<>(sourceCollection.size()); + for (final TItem item : sourceCollection) { + if (filter.call(item)) { + result.add(item); + } + } + return result; + } + + @NonNull + private final ObservableList filteredList = new ObservableList<>(); + @NonNull + private Collection sourceCollection = new ArrayList<>(); + @Nullable + private Func1 filter; + + public ObservableFilteredList() { + filteredList.observeChanges().subscribe(change -> { + //do not change - bug of RetroLambda + notifyAboutChanges(change); + }); + } + + public void setSourceCollection(@NonNull final Collection sourceCollection) { + this.sourceCollection = sourceCollection; + if (filter != null) { + filteredList.set(filterCollection(sourceCollection, filter)); + } else { + filteredList.set(sourceCollection); + } + } + + public void setFilter(@NonNull final Func1 filter) { + this.filter = filter; + filteredList.set(filterCollection(sourceCollection, filter)); + } + + @Override + public int size() { + return filteredList.size(); + } + + @NonNull + @Override + public TItem get(final int position) { + return filteredList.get(position); + } + + @NonNull + @Override + public Observable loadItem(final int position) { + return filteredList.loadItem(position); + } + +} diff --git a/src/main/java/ru/touchin/roboswag/core/observables/collections/ObservableList.java b/src/main/java/ru/touchin/roboswag/core/observables/collections/ObservableList.java index 805bcac..5dcd531 100644 --- a/src/main/java/ru/touchin/roboswag/core/observables/collections/ObservableList.java +++ b/src/main/java/ru/touchin/roboswag/core/observables/collections/ObservableList.java @@ -86,9 +86,33 @@ public class ObservableList extends ObservableCollection { notifyAboutChange(new Change(Change.Type.CHANGED, position, 1)); } - public void set(@NonNull final Collection items) { - clear(); - addAll(items); + public void set(@NonNull final Collection newItems) { + int currentItemsStart = 0; + for (final TItem item : newItems) { + boolean found = false; + for (int i = currentItemsStart; i < items.size(); i++) { + if (item.equals(items.get(i))) { + found = true; + for (int j = currentItemsStart; j < i; j++) { + items.remove(currentItemsStart); + } + notifyAboutChange(new Change(Change.Type.REMOVED, currentItemsStart, i - currentItemsStart)); + break; + } + } + if (!found) { + add(currentItemsStart, item); + } + currentItemsStart++; + } + + if (currentItemsStart < items.size()) { + final int itemsToRemove = items.size() - currentItemsStart; + for (int i = 0; i < itemsToRemove; i++) { + items.remove(currentItemsStart); + } + notifyAboutChange(new Change(Change.Type.REMOVED, currentItemsStart, itemsToRemove)); + } } public boolean isEmpty() { diff --git a/src/main/java/ru/touchin/roboswag/core/observables/collections/loadable/LoadingGrowingList.java b/src/main/java/ru/touchin/roboswag/core/observables/collections/loadable/LoadingGrowingList.java index 1efb353..019e55d 100644 --- a/src/main/java/ru/touchin/roboswag/core/observables/collections/loadable/LoadingGrowingList.java +++ b/src/main/java/ru/touchin/roboswag/core/observables/collections/loadable/LoadingGrowingList.java @@ -56,7 +56,7 @@ public class LoadingGrowingList> this.loadingMoreRequestCreator = loadingMoreRequestCreator; innerList.observeChanges().subscribe(change -> { //do not change - bug of RetroLambda - notifyAboutChange(change); + notifyAboutChanges(change); }); }