Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MutableLiveData ArrayList is empty even after postValue() Kotlin

I am now stuck and currently wondering why my mutable arraylist returns null even if it is being updated with postvalue(). I tried to display it using Toast and it displayed [] which I think is null. It had no space in between so it looked like a box. I did toString() it as well in order to show the text. How would I be able to solve this problem?

Here is my Main Activity:

val list = ArrayList<String>()
list.add("text1")
list.add("text2")
val viewmodel = ViewModelProviders.of(this).get(viewmodel::class.java)
viewmodel.Testlist.postValue(list)

ViewModel:

class viewmodel: ViewModel() {
    val Testlist: MutableLiveData<ArrayList<String>> = MutableLiveData()
    init {
        Testlist.value = arrayListOf()
    }
}

Fragment:

Top area:

activity?.let {
    val viewmodel = ViewModelProviders.of(this).get(viewmodel::class.java)
    observeInput(viewmodel)
}

Bottom area:

private fun observeInput(viewmodel: viewmodel) {
    viewmodel.Testlist.observe(viewLifecycleOwner, Observer {
        it?.let {
            Toast.makeText(context, it.toString(), Toast.LENGTH_LONG).show()
        }
    })
}
like image 537
Uni Avatar asked Jul 20 '26 19:07

Uni


2 Answers

You post the value to the LiveData object in the activity's viewmodel, which isn't the same instance as the fragment's viewmodel. Let's take look at the way you instantiate the viewmodel in your fragment:

activity?.let {
    // activity can be refered by the implicit parameter `it`
    // `this` refers to the current fragment hence it's the owner of the view model
    val viewmodel = ViewModelProviders.of(this).get(viewmodel::class.java)
    observeInput(viewmodel)
}

To get a viewmodel that is shared between your activity and fragment you have to pass the activity as its owner:

activity?.let { val viewmodel = ViewModelProviders.of(it).get(viewmodel::class.java) }
like image 169
jsamol Avatar answered Jul 23 '26 07:07

jsamol


Probably you can see developer guide example to resolve your problem

https://developer.android.com/topic/libraries/architecture/viewmodel.html#kotlin

// shared viewmodel

 class SharedViewModel : ViewModel() {
    private val usersList: MutableLiveData<List<String>>()

    fun getUsers(): LiveData<List<String>> {
        return usersList
    }

    fun setUsers(users: List<String>) {
        usersList.value = users
    }
 }

// Attach ViewModel In Activity onCreate()

val model = ViewModelProviders.of(this)[SharedViewModel::class.java]

val list = arrayListOf<String>()
list.add("user1")
list.add("user2")

model.setUsers(list)

// Get same ViewModel instance In fragment onCreateView()

model = activity?.run {
        ViewModelProviders.of(this)[SharedViewModel::class.java]
} ?: throw Exception("Invalid Activity")

model.getUsers().observe(this, Observer<List<User>>{ users ->
      // update UI
})
like image 27
Ashok Kumar Avatar answered Jul 23 '26 08:07

Ashok Kumar