LiveData is not updating its value after first call

前端 未结 4 867
谎友^
谎友^ 2020-12-08 21:34

I have been beating my head against the wall and I cannot understand why this is happening. I am working with the new Architectural Components for Android and I am having pr

4条回答
  •  情深已故
    2020-12-08 21:45

    Writing an answer for better discussion.

    So I have (in Kotlin, sry) a model that is a list of notes (it’s just a sandbox app to play w/all this) and here’s my architecture: I don’t have a Repo, but I have Activity -> ViewModel -> Dao.

    So Dao exposes a LiveData>

    @Query("SELECT * FROM notes")
    fun loadAll(): LiveData>
    

    My ViewModel… exposes it through:

    val notesList = database.notesDao().loadAll()

    and my Activity (onCreate) does…

        viewModel.notesList.observe(this,
                Observer> { notes ->
                    if (notes != null) {
                        progressBar?.hide()
                        adapter.setNotesList(notes)
                    }
                })
    

    This works. The adapter is a RecyclerView adapter that does literally nothing but:

     fun setNotesList(newList: MutableList) {
            if (notes.isEmpty()) {
                notes = newList
                notifyItemRangeInserted(0, newList.size)
            } else {
                val result = DiffUtil.calculateDiff(object : DiffUtil.Callback() {
                    override fun getOldListSize(): Int {
                        return notes.size
                    }
    
                    override fun getNewListSize(): Int {
                        return newList.size
                    }
    
                    override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
                        return notes[oldItemPosition].id == newList[newItemPosition].id
                    }
    
                    override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
                        val (id, title, _, priority) = newList[newItemPosition]
                        val (id1, title1, _, priority1) = notes[oldItemPosition]
                        return id == id1
                                && priority == priority1
                                && title == title1
                    }
                })
                notes = newList
                result.dispatchUpdatesTo(this)
            }
        }
    

    If ANY other part of the app modifies that list of notes, the adapter updates automagically. I hope this gives you a playground to try a simple(r?) approach.

提交回复
热议问题