2

Depending on the number of items in the collection, I want to do certain actions.

For example

if i have 1 item in collection -> doFirstAction()
if i have 2 or more items in collection -> doSecondAction()
if i have 2 or more items in collection and deleted all instead one -> doSecondAction()

On this basis i need to check changing the list.

I found something similar: ObservableList. And it seems to solve my problem, but unfortunately I do not know how it can be used correctly.

In my class i need check this collection:

var viewModels: List<ConnectionViewModel> = emptyList()

UPDATE: With this answer i write smth like this:

var viewModels: ObservableList<ConnectionViewModel> = ObservableArrayList<ConnectionViewModel>()

And add listener on my collection:

fun setOnDataChange() {
    viewModels.addOnListChangedCallback(object :
        ObservableList.OnListChangedCallback<ObservableList<ConnectionViewModel>>() {
        override fun onChanged(sender: ObservableList<ConnectionViewModel>?) {}

        override fun onItemRangeRemoved(
            sender: ObservableList<ConnectionViewModel>?,
            positionStart: Int,
            itemCount: Int
        ) {
            showBiometricConfirmation = showConfirmation(itemCount)
        }

        override fun onItemRangeMoved(
            sender: ObservableList<ConnectionViewModel>?,
            fromPosition: Int,
            toPosition: Int,
            itemCount: Int
        ) {}

        override fun onItemRangeInserted(
            sender: ObservableList<ConnectionViewModel>?,
            positionStart: Int,
            itemCount: Int
        ) {
            showBiometricConfirmation = showConfirmation(itemCount)
        }

        override fun onItemRangeChanged(
            sender: ObservableList<ConnectionViewModel>?,
            positionStart: Int,
            itemCount: Int
        ) {}
    })
}

private fun showConfirmation(itemCount: Int): Boolean {
    return itemCount != 1
}

But i have some problem I need check the number in the collection. If number was 3 and after i delete 2, i also need to call doSecondAction(). but if collection number was 1, need to call doFirstAction()

Morozov
  • 4,968
  • 6
  • 39
  • 70

3 Answers3

3

First you should enable dataBinding in gradle, inside android{}

android {
    ......
    dataBinding {
        enabled = true
    }
}

Then, in your code create empty list:

   val list: ObservableList<String> = ObservableArrayList<String>()

You can set listener like this:

list.addOnListChangedCallback(object:ObservableList.OnListChangedCallback<ObservableList<String>>(){
            override fun onChanged(sender: ObservableList<String>?) {
                Log.d("Misha", "changed")
            }

            override fun onItemRangeRemoved(sender: ObservableList<String>?, positionStart: Int, itemCount: Int) {
                ...
            }

            override fun onItemRangeMoved(sender: ObservableList<String>?, fromPosition: Int, toPosition: Int, itemCount: Int) {
                ...
            }

            override fun onItemRangeInserted(sender: ObservableList<String>?, positionStart: Int, itemCount: Int) {
                ...
            }

            override fun onItemRangeChanged(sender: ObservableList<String>?, positionStart: Int, itemCount: Int) {
                ...
            }    
 })

You can add(remove) values like this, or with other methods:

 list.addAll(0, listOf("Misha", "Akopov"))
Misha Akopov
  • 12,241
  • 27
  • 68
  • 82
  • in my case i need change `var viewModels: List = emptyList()` on `var viewModels: ObservableList = ObservableArrayList()` ? And after this whole my logic with size of collection i need to insert in `onChanged`? – Morozov Nov 21 '19 at 16:38
  • Yes, you will have listener on that list – Misha Akopov Nov 21 '19 at 19:03
  • sorry but i don't understan how i can see that my collection was changed? For example as it is possible to write down a condition that a pier the size of the collection was three and became one for example? – Morozov Nov 22 '19 at 12:46
  • Please read this one, parametr descriptions https://developer.android.com/reference/android/databinding/ObservableList.OnListChangedCallback#onitemrangechanged – Misha Akopov Nov 22 '19 at 16:29
  • This is about update content in collection. But I need to react to changes in the number of items in the collection itself – Morozov Nov 25 '19 at 12:27
1

One way is to use ViewModel + Observer pattern.

  1. ViewModel. We put the list that will be observed here
// SETTER
val _myList = MutableLiveData<MutableList<Item>>()

// GETTER
val myList: LiveData<MutableList<Item>> = _myList

init {

   _myList.value.add(item1)
   ... add remaining items

}

  1. Activity. We modify / set the list and observe the list changes.
mViewModel.myList.observe(this, Observer{

   // it == myList
   if (it.size == 1) doFirstAction()
   else if (it.size >= 2) doSecondAction()
   else if (it.size >= 2 && deleted all instead one) do second action

})

// MODIFY LIST
mViewModel._myList.value.remove(item2)
mViewModel._myList.value.add(item4)

There will be a lot of null check warning. And later on you might wanna make _myList private and do this

nfl-x
  • 487
  • 1
  • 6
  • 13
-1

Resolve my problem with next solution:

Create next var:

private var quickConfirmMode: Boolean = false

And use it in my custom setter:

var viewModels: List<ConnectionViewModel> = emptyList()
    set(value) {
        quickConfirmMode = value.size == 1 && (field.size == 1 || field.isEmpty())
        field = value
    }

Solution: Where field is backing property, which save my value. More information about getters and setters you can read here. So in my custom setter i check my new and old value, then I set the value for quickConfirmMode.

Morozov
  • 4,968
  • 6
  • 39
  • 70