回收者视图不会使用实时数据自动更新

时间:2020-08-12 22:43:10

标签: android kotlin android-recyclerview android-livedata

我的观察者正在工作,每当输入新记录时都会被调用

问题在于回收站视图仅显示一条记录,并且由于保存setClickListener而从未更新以显示其他记录。

我可以在我的数据库(带有LiveData的房间)中验证我有多个记录,适配器或ViewHolder出现问题。

PS ,此外,对于使用适配器的样式应做的事情的任何修改,都非常欢迎。我希望我做对了。

MainActivity onCreate方法

    viewModel = ViewModelProvider(this).get(BookViewModel::class.java)

    save.setOnClickListener {
        val book = Book(UUID.randomUUID().toString(), "author 2", "book 2")
        viewModel.insert(book)
    }

    val bookListAdapter = BookListAdapter(this)
    recyclerView.adapter = bookListAdapter
    recyclerView.layoutManager = LinearLayoutManager(this)

    viewModel.allBooks.observe(this, Observer { books ->
        books?.let {
            Log.d(TAG, "onCreate: changed")
            bookListAdapter.setBooks(books)
        }
    })

MainActivity中的静态类

private class BookListAdapter(private val context: Context): RecyclerView.Adapter<BookListAdapter.BookViewHolder>() {

    private var bookList: List<Book> = mutableListOf()

    // getting called only once
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BookListAdapter.BookViewHolder {
        val itemView = LayoutInflater.from(context).inflate(R.layout.list_item, parent, false)
        return BookViewHolder(itemView)
    }

    override fun onBindViewHolder(holder: BookListAdapter.BookViewHolder, position: Int) {
        val book = bookList[position]
        holder.setData(book.author, book.book, position)
    }

    override fun getItemCount(): Int {
        Log.d("inner", "getItemCount: ${bookList.size}") // this return correct size
        return bookList.size
    }

    fun setBooks(it: List<Book>?) {
        bookList = it!!
        notifyDataSetChanged()
    }

    private class BookViewHolder(itemView: View): RecyclerView.ViewHolder(itemView) {

        fun setData(a: String, b: String, p: Int) {
            itemView.author.text = a
            itemView.book.text = b
        }
    }

}

1 个答案:

答案 0 :(得分:0)

基于以下答案:How to update RecyclerView Adapter Data?我认为您必须从观察者方法notifyDataSetChanged而不是适配器类内部。

viewModel.allBooks.observe(this, Observer { books ->
    books?.let {
        Log.d(TAG, "onCreate: changed")
        bookListAdapter.setBooks(books)
        bookListAdapter.notifyDataSetChanged()
    }
})
fun setBooks(it: List<Book>) {
    bookList = it
}

此外,我认为您在使用会议室时可以尝试使用DiffUtil。它会在需要刷新时自动刷新布局,并且比每次更改数据时调用notifyDataSetChanged都要快。