1

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.

Shawn
  • 1,222
  • 1
  • 18
  • 41
  • in the training you posted, they use ViewModel, any particular reason why it's missing in your samples? LiveData like this fits much better in the ViewModel, in Activity it is kind of pointless – Stachu Oct 05 '20 at 16:17
  • I was trying to do it without ViewModel at first and then add it later down the road. – Shawn Oct 05 '20 at 16:27

2 Answers2

0

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)
    } 
}
  • This is an interesting approach, how do you go about editing(adding and removing) the list after its posted to LiveData. – Shawn Oct 05 '20 at 15:13
  • I don't know what is your use case but that livedata is useless currently you can simply use a mutableList and do the operations and submit it to adapter. Just make sure to copy items before send it to adapter like. mAdapter.submitList(it.map{item -> item.copy()}) – mehmet salim ayan Oct 05 '20 at 15:17
0

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)
    }
}
Vishal Pawar
  • 4,324
  • 4
  • 28
  • 54