0

Inside the fragment of a tabbed activity:

override fun onActivityCreated(savedInstanceState: Bundle?) {
    super.onActivityCreated(savedInstanceState)
    serverSetVM = ViewModelProvider(activity!!).get(ServersViewModel::class.java)

    serverList = ArrayList(serverSetVM.get())
    rv = rv_serverList // findViewById 
    rv.layoutManager = LinearLayoutManager(context)
    rv.adapter = ServerListRevAdapter(context!! ,serverList) 

    serverSetVM.serverSetLiveData.observe(viewLifecycleOwner,  Observer {

        Log.v ("MainAct", "Inside OBSERVER")
        serverList = ArrayList(serverSetVM.get())
        rv.adapter!!.notifyDataSetChanged()
    })
}

Also;

val serverSetLiveData = MutableLiveData<HashSet<Server>>() // Inside ViewModel class

observe() function does not seem to work. When the value of ServerSetVM is modified inside the same fragment (by the functions defined in ViewModel class, i.e. add()), recyclerView is not updated. According to Logcat output, Observer lambda is called only after onCreateView().

I confirmed MutableLiveData gets updated but Observer{} lambda is not called. Do I need to correct my notion about ViewModels?

EDIT (SOLUTION): Use " = " operator to modify the MutableLiveData value so that observer can detect it. Even serverSetLiveData.value=serverSetLiveData.value does the job.

Xfce4
  • 557
  • 5
  • 28
  • This only works if `serverSetVM` is mutable list, which it shouldn't have to be. Should be using `adapter.setItems(list)` or something like that. – EpicPandaForce Mar 05 '20 at 21:10
  • What do you mean by "Should be using `adapter.setItems(list)` or something like that" ? – Xfce4 Mar 05 '20 at 21:25

2 Answers2

0

Observer only observe if you call setValue() or postValue() method of MutableLiveData

where you are calling the setValue() or postValue() function for serverSetLiveData . eg. serverSetLiveData.setValue(serverList) or serverSetLiveData.postValue(serverList). in the code.

Black4Guy
  • 641
  • 11
  • 28
  • `ServerSetVM.add()` inside the fragment calls `serverSetLiveData.value!!.add()` inside the ViewModel class. Since there is no `setValue()` or `postValue()` method in Kotlin maybe I should update `serverSetLiveData.value` by the "=" operator instead of `add()`. – Xfce4 Mar 05 '20 at 09:02
  • Yes kotlin replace setValue() and getValue() with value. if you use like serverSetLiveData.value=serverList. Means you are using setValue() and if you use like serverSetLiveData.value. Means you are using getValue(). yes postValue() function exist in kotlin – Black4Guy Mar 05 '20 at 09:09
  • 1
    to use livedata you must use `livedata.value` or `livedata.postValue()` in viewModel(), include when some update with your list. live data will not trigger when you just do "livedata.value.list.add('new Item)", you must set value for live data to trigger it. `livedata.value = newList` something like that. – Ali bana Mar 05 '20 at 09:47
  • @Black4Guy Thank you. "=" operator worked. Would be nice if you edit your answer for Kotlin and I accept it. Btw, even though I get inside the `Observer` Lambda, recyclerView adapter is not updated. Why do you think? – Xfce4 Mar 05 '20 at 19:39
  • 1
    `setValue` in Java is the same as `.value =` in Kotlin, see the interop guide on property accessors. – EpicPandaForce Mar 05 '20 at 22:31
0

Obervre gets triggered only if you call .value =