Home > Mobile >  RxJava - Kotlin
RxJava - Kotlin

Time:04-07

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
})
  • Related