ListAdapter submitList 不更新

ListAdapter submitList not updating

我在 RecyclerView 中遇到分页无限滚动的问题,我正在使用 .addAll()

添加所有新项目
 movieList.addAll(it.movieList)
 adapter.submitList(movieList)
 Log.wtf("WTF", movieList.size.toString())

每当我们从 API 收到成功响应时,大小就会不断增加,这表明列表确实正在填充,但 RecyclerView 中的项目保持不变,submitList() 似乎只在一开始有效打电话。

这是我的 DiffUtil class 和适配器

class DiffUtilMovies : DiffUtil.ItemCallback<MovieItem>() {

    // DiffUtil uses this test to help discover if an item was added, removed, or moved.
    override fun areItemsTheSame(oldItem: MovieItem, newItem: MovieItem): Boolean {
        return oldItem.id == newItem.id
    }

    // Check whether oldItem and newItem contain the same data; that is, whether they are equal.
    // If there are differences between oldItem and newItem, this code tells DiffUtil that the item has been updated.
    override fun areContentsTheSame(oldItem: MovieItem, newItem: MovieItem): Boolean {
        // Check for now if there is a difference on the price, removing specific fields
        // means checking all the data for changes
        return oldItem.title == newItem.title
    }

}


class MovieAdapter(private val context: Context) : ListAdapter<MovieItem, MovieAdapter.ItemView>(DiffUtilMovies()) {

    private var isDetached: Boolean = false

    class ItemView(itemView: MovieCardBinding) : RecyclerView.ViewHolder(itemView.root) {
        val titleTxt = itemView.titleTxt
        val rateTxt = itemView.rateTxt
        val rateBar = itemView.rateBar
        val imageThumb = itemView.thumbnail
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemView {
        return ItemView(
            MovieCardBinding.inflate(
                LayoutInflater.from(parent.context),
                parent,
                false
            )
        )
    }

    override fun onBindViewHolder(holder: ItemView, position: Int) {
        holder.apply {

            val movieItem = getItem(position)

            titleTxt.text = movieItem.title
            rateTxt.text = movieItem.voteAverage.toString()

            val rateAvg = movieItem.voteAverage?.toFloat() ?: run {
                0.0f
            }

            rateBar.rating = rateAvg/2

            if (!isDetached)
                GlideApp.with(context)
                    .load(context.getString(R.string.image_link,AppConfig.image_endpoint, movieItem.posterPath))
                    .thumbnail(GlideApp.with(context).load(R.drawable.loading).centerCrop())
                    .error(R.drawable.no_image)
                    .into(imageThumb)

            this.itemView.setOnClickListener {

                try {

//                    context.startActivity(Intent(context, AssetInfoActivity::class.java).apply {
//                        putExtra(context.getString(R.string.assets), movieItem)
//                    })

                }
                catch (ignored: Exception){
                    // The user probably already leave before the activity started
                }

            }

        }
    }

    override fun onDetachedFromRecyclerView(recyclerView: RecyclerView) {
        super.onDetachedFromRecyclerView(recyclerView)
        isDetached = true
    }
}

ListAdapter 不适用于可变列表。这是因为如果你修改 List 的内容,当它试图比较旧列表和新列表的内容时,它会将同一个列表与自己进行比较。没有旧列表实例仍然保留旧内容,因此无法检测到任何差异。

您应该创建一个新列表,而不是改变原始列表,例如

movieList = movieList + it.movieList
adapter.submitList(movieList)

或者,您可以使用可变支持列表,但在将其传递给 submitList 时始终创建一个副本。即使是第一次传递列表时,您也必须使用副本,这样它就永远不会引用您的可变列表。

movieList.addAll(it.movieList)
adapter.submitList(movieList.toList())