A thin wrapper around Java Collections using RxJava2 in which you can observe the insertions,removals and modifications.
Inspired from observable collections in JavaFX and observable properties in Swift.
- Compatible with Java 1.7+ and Android.
- Implements standard collection interfaces such as List, Set, Queue and Map.
- Support for observing insertions, modifications and removals.
- All errors are handled. i.e No runtime crashes.
- Minimal overhead with method count < 200.
- Uses RxJava Subject behind the scenes.
- Fully extensible - ability to create your own data structure and specify custom subject.
- Gradle
dependencies {
compile 'com.krupalshah:observablecollections:1.0.5'
}
- Maven
<dependency>
<groupId>com.krupalshah</groupId>
<artifactId>observablecollections</artifactId>
<version>1.0.5</version>
<type>pom</type>
</dependency>
- Use CollectionsFactory to wrap your collection with observable collection:
List<Contact> mContacts = new ArrayList<>(); //your collection
ObservableList<Contact> contactObservableList = CollectionsFactory.observableList(mContacts); //pass in observable... method
- Call
subject()
and subscribe the subject where you want to observe the changes.
contactObservableList
.subject() //get subject
.subscribe(new Consumer<Change>() { //you can apply schedulers if you want
@Override
public void accept(Change change) throws Exception {
onChangeDetected(change); //all changes will be received here
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
throwable.printStackTrace();
}
});
- You can determine what kind of change was performed by checking type of
Change<Source,Result>
.
Insertion
,Removal
andModification
all three extendsChange
and contains methods to get new/updated/removed items, their size and original collection before changes.
private void onChangeDetected(Change<ObservableList<Contact>, Collection<Contact>> change) {
if (change instanceof Insertion) {
//items inserted (i.e add/addAll/put/putAll/offer etc. called)
} else if (change instanceof Modification) {
//items updated (i.e set/put/putAll etc. called)
} else if (change instanceof Removal) {
//items removed (i.e remove/removeAll/poll/clear etc. called)
}
}
You will get information about what exactly has been changed by calling following methods:
-
For all changes :
getAssociatedCollection()
will return source observable collection for which changes are detected.getOriginalItems()
will return original items before change.sizeOfOriginalItems()
will return size of original items before change.
-
For
Insertion
:getInsertedItems()
will returnCollection
of added items. The collection may be immutable.sizeOfInsertedItems()
will return size of added items.
-
For
Removal
andModification
, similar methods have been defined to get collection of removed/updated items and their size.
For more details, please have a look at Change
and its subclasses here.
- Internally, the library uses PublishSubject by default. But, you can pass your custom subject in the second parameter of
observe...
methods:
BehaviorSubject<Change> behaviorSubject = BehaviorSubject.create();
ObservableMap<String,String> observableMap = CollectionsFactory.observableMap(new ArrayMap<String, String>(), behaviorSubject);
There is a sample Android app here which only demonstrates ObservableList
for now.ChangeSourceFragment
changes the ObservableList
, which is observed in ChangeObserverFragment
.
Also note that ObservableCollections is a Java library, not specific to only Android. So, it can be used with any Java/Android project.
Copyright 2017 Krupal Shah
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.