LiveData with a list

4.5k views Asked by At

I'm want to observe a MutableList so when items get added or removed from the MutableList the DiffUtil will update the RecycerView. I think the best approach to update the list is to use LiveData but I'm not able to add or remove items from the MutableList.

I've been following this code lab below to try and help me along.

https://codelabs.developers.google.com/codelabs/kotlin-android-training-diffutil-databinding/#4

Main Activity

class MainActivity : AppCompatActivity() {
    val list: LiveData<MutableList<User>>? = null
    var mAdapter = RVAdapter

    override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
        addUser()
        val rv = findViewById<RecyclerView>(R.id.recycler_view)
        rv.apply {
            LayoutManager = LinearLayoutManager(baseContext, LinearLayoutManager.VERTICAL, false)
            adapter = mAdapter
        }

        list?.observe(viewLifeCycleOwner, Observer {
            it?.let {
                mAdapter.submitList(it)
            }
        }
    }

    private fun addUser() {
        list.add(User("Shawn", 1)
        list.add(User("Shannon", 2)
        list.add(User("Steve", 3)
        list.add(User("Sara", 4)

    } 
}

User Data class

data class User(val name: String, val accountNumber: Int) {
}

Adapter

class RVAdapter : ListAdapter<User, RVAdapter.ViewHolder>(MyDiffCallback()) {

    class MyDiffCallback : DiffUtil.ItemCallback<User>() {
        override fun areItemsTheSame(oldItem: User, newItem: User): Boolean {
            return oldItem.name == newItem.name
        }

        override fun areContentsTheSame(oldItem: User, newItem: User): Boolean {
            return oldItem == newItem
        }
    }

   ... 
}

Here is my code as it currently stands I can't add or remove items from the list and the ViewLifecycleOwner is undefined.

2

There are 2 answers

0
Vishal Pawar On

May be this will help. You can achive what you want but you always have to combine LiveData with ViewModel for getting data and updating it. Google recommends to do it that way.

class MainActivity : AppCompatActivity() {
    val list: LiveData<MutableList<User>> = MutableLiveData<List<User>>().apply{
       postValue(mutableListOf<User>())
    }
    var mAdapter = RVAdapter

    override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
        addUser()
        val rv = findViewById<RecyclerView>(R.id.recycler_view)
        rv.apply {
            LayoutManager = LinearLayoutManager(baseContext, LinearLayoutManager.VERTICAL, false)
            adapter = mAdapter
        }

        list?.observe(viewLifeCycleOwner, Observer {
            it?.let {
                mAdapter.submitList(it)
            }
        }
    }

    private fun addUser() {
        
        val userList = list.getValue()
        userList .add(User("Shawn", 1)
        userList .add(User("Shannon", 2)
        userList .add(User("Steve", 3)
        userList .add(User("Sara", 4)
        list.postValue(userList)

    } 

    private fun editUser() {
       val userList = list.getValue()
        userList.add(User("Shawn", 21)
        
        list.postValue(userList)
    }
}
2
mehmet salim ayan On

First you need initialize your livedata and post your list to it. You can check below example

class MainActivity : AppCompatActivity() {
    val list = MutableLiveData<List<User>?>()
    var mAdapter = RVAdapter

    override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
        addUser()
        val rv = findViewById<RecyclerView>(R.id.recycler_view)
        rv.apply {
            LayoutManager = LinearLayoutManager(baseContext, LinearLayoutManager.VERTICAL, false)
            adapter = mAdapter
        }

        list.observe(this, Observer {
            it?.let {
                mAdapter.submitList(it)
            }
        }
    }

    private fun addUser() {
        val newList = mutableListOf<User>()
        newList.add(User("Shawn", 1)
        newList.add(User("Shannon", 2)
        newList.add(User("Steve", 3)
        newList.add(User("Sara", 4)
        list.postValue(newList)
    } 
}