I am working on an integration of a bluetooth sdk,
It forces me to have a static arraylist where the sdk module is hosting the read data, this statement is in Java
public ArrayList<ReaderDevice> tagsList = new ArrayList<>();
In my Kotlin activity I have the static reference
lateinit var sharedObjects: SharedObjects
To get this list of my fragments I use
HomeActivity.sharedObjects.tagsList
What I need is "some way" no matter how "dirty" to be able to have a "listener" -"observer" to know from my fragments when a new element is added to take some action x but only when I do the "onnext" can I get the size, otherwise it doesn't refresh, I guess it's because it "is copied" but it doesn't have the same reference, can I somehow put the static reference to my viewmodel propertys? I'm lost how to see this list
Try to create the observable like this
//fragment
viewmodel.setReadTagsList.onNext(HomeActivity.sharedObjects.tagsList)
//viewmodel
val setReadTagsList = PublishSubject.create<List<ReaderDevice>>()
private val _tags = BehaviorSubject.create<List<ReaderDevice>>()
setReadTagsList
.bind(_tags)
.disposedBy(disposeBag)
setReadTagsList
.withLatestFrom(_tags){_, o1 -> o1}
.map { "${it.size}" }
.bind(_errorMessage)
.disposedBy(disposeBag)
CodePudding user response:
java.util.ArrayList
doesn't support listening (on adding/removing elements), you need to use something different instead.
If you have the option of setting HomeActivity.sharedObjects.tagsList
, you can use the following approach:
Set it to another list with the capability. You could either use an existing list supporting that or create a new one that forwards all operation to another list or extends ArrayList
and intercepts the methods by overriding like that:
class WatchableArrayList<T>(val listener:(Int, T? , T? )->Unit):ArrayList<T>() {
override fun add(elem: T): Boolean {
val index = size
val ret = super.add(elem)
listener.invoke(index, elem, null)
return ret
}
//similar for other methods
}
This creates a class extending ArrayList
that takes a high-order function as a constructor parameter (that takes the index added and removed element as parameters).
You can then create an instance of that and set HomeActivity.sharedObjects.tagsList
to that instance like that:
HomeActivity.sharedObjects.tagsList = WatchableArrayList((index, added, removed)->{
//handler here
})
However, you might want to use a wrapper pattern instead of inheritance here:
class WatchableListWrapper<T>(val wrapped: MutableList<T>, val listener:(Int, T? , T? )->Unit) {
override fun add(elem: T): Boolean {
val index = size
val ret = wrapped.add(elem)
listener.invoke(index, elem, null)
return ret
}
//similar for other methods
}
HomeActivity.sharedObjects.tagsList = WatchableListWrapper(HomeActivity.sharedObjects.tagsList, (index, added, removed)->{
//handler here
})