PagedListAdapter.submitList()更新现有项目时表现怪异 [英] PagedListAdapter.submitList() Behaving Weird When Updating Existing Items

查看:148
本文介绍了PagedListAdapter.submitList()更新现有项目时表现怪异的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有关此主题的小故事:该应用程序仅在确认后使用对话框更新单击的行的值.在会议室数据库上使用分页方案.

Little story of this topic : the app just updating clicked row's values with dialog when confirmed. Uses pagination scenario on room database.

添加或删除项目时,将获取最新的数据集并将其传递到submitList方法,然后所有更改都可以看到并正常工作.

When an item added or removed, the latest dataset is fetched and passed to submitList method, then all changes are seen and worked well.

问题开始于此,如果现有项目已更新,则再次正确地获取了最新的数据集并将其传递给submitList,但是这次似乎没有变化.

The problem starts there, if an existing item updated, again the latest dataset is fetched properly and passed to submitList, but this time changes didn't seem.

当我调试 DIFF_CALLBACK 并将我的项目捕获在 areItemsTheSame 中时, newHistory oldHistory 值相同!(如何!)

When i debug the DIFF_CALLBACK and caught my item in areItemsTheSame, the newHistory and oldHistory values are same! (How!)

submitList 方法中可能存在任何错误?

There could be any bug in submitList method ?

  • 房间v .: 2.1.0-alpha02
  • 分页v.:2.1.0-beta01

初始化后,观察从房间获取列表并传递给 mHistoryAdapter.submitList(it).然后,如果我更新了一项,观察会再次被触发(并且我在参数 it 中看到更新的值)并传递给 submitList .

After initializing, observe fetches list from room and passes to mHistoryAdapter.submitList(it). Then if i update an item, observe gets triggered again(and i'm seeing updated value in param it) and passes to submitList.

不幸的是,适配器不会改变...

Unfortunately, adapter wont change...

    mResolvedAddressViewModel = ViewModelProviders.of(this).get(ResolvedAddressViewModel::class.java)
    mResolvedAddressViewModel.getAddresses(false).observe(this, Observer {
        mHistoryAdapter.submitList(it)
    })


所有部分


All the parts

型号

@Parcelize
@Entity
data class ResolvedAddress(
    @PrimaryKey var id: String = UUID.randomUUID().toString(),
    var requestedLat: Double = 0.0,
    var requestedLon: Double = 0.0,
    var requestedAddress: String = "",
    var lat: Double,
    var lon: Double,
    var address: String,
    var country: String,
    var countryCode: String,
    var city: String,
    var alias: String? = null,
    var favorite: Boolean = false,
    var provider: String? = null,
    var lastUseDate: Long = 0L) : Parcelable

适配器

class HistoryAdapter(var context: Context)
: PagedListAdapter<ResolvedAddress, HistoryItemHolder>(DIFF_CALLBACK) {

    companion object {
        private val DIFF_CALLBACK = object : DiffUtil.ItemCallback<ResolvedAddress>() {
            override fun areItemsTheSame(
                oldHistory: ResolvedAddress, newHistory: ResolvedAddress): Boolean {
                return oldHistory.id == newHistory.id
            }

            override fun areContentsTheSame(
                oldHistory: ResolvedAddress, newHistory: ResolvedAddress): Boolean {
                return oldHistory == newHistory
            }
        }
    }
}

片段

class HistoryFragment : Fragment() {
    private lateinit var mHistoryAdapter: HistoryAdapter
    private lateinit var mResolvedAddressViewModel: ResolvedAddressViewModel

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, 
        savedInstanceState: Bundle?): View? {
        return inflater.inflate(R.layout.fragment_history, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        recyclerViewHistory.setHasFixedSize(true)
        recyclerViewHistory.layoutManager = LinearLayoutManager(activity)
        recyclerViewHistory.itemAnimator = DefaultItemAnimator()

        mHistoryAdapter = HistoryAdapter(context!!)
        recyclerViewHistory.adapter = mHistoryAdapter

        mResolvedAddressViewModel = ViewModelProviders.of(this)
        .get(ResolvedAddressViewModel::class.java)

        mResolvedAddressViewModel.getAddresses(false).observe(this, Observer {
            mHistoryAdapter.submitList(it)
        })
    }
}

推荐答案

该问题中缺少一些有助于提供更详细答案的问题.

There's a couple things missing from the question that could help provide a more detailed answer.

例如您的 RecyclerView.Adapter 是什么样的?它会扩展 PagedListAdapter 吗?

Ex. What does your RecyclerView.Adapter look like? Does it extend PagedListAdapter?

您的模型类是什么样的?它是Kotlin数据类吗?

What does your model class look like? Is it a Kotlin data class?

为了提供答案,让我们假设那些未知数是我们所期望的.

For the sake of providing an answer, let's assume those unknowns are what we expect.

如果我理解这个问题,似乎您只是在更新一个项目,而没有删除或添加任何项目.因此, DiffUtil.ItemCallback areItemsTheSame 将始终返回true,因为旧列表和新列表的大小均未修改.意思是,如果您更新了一项,则可能是更新了其内容,而不是将其从列表中删除.

If I understand the question, it seems like you're just updating an item and not removing or adding any items. Therefore, the DiffUtil.ItemCallback's areItemsTheSame will always return true, because the old list and new list has not been modified in terms of their size. Meaning, if you've updated an item, you've probably updated it's contents and not removed it from the list.

因此, areItemsTheSame 将返回true,因为它们的ID仍然相同.

Therefore, areItemsTheSame will return true, because their ids are still the same.

由于更新了项目的内容,第二种方法 areContentsTheSame 更有可能返回false.

It's more likely that the second method, areContentsTheSame will return false since you've updated the item's content.

如果您的模型类 ResolvedAddress 是Kotlin数据类,则在比较从旧列表和列表中更新的项目时,方法 areContentsTheSame 应该返回false.新清单.此时,这将触发适配器中的 onBindViewHolder 方法,以便您将该项目与更新的数据重新绑定.

If your model class, ResolvedAddress, is a Kotlin data class, then the method areContentsTheSame should return false when comparing the item that was updated from the old list and the new list. This should trigger the onBindViewHolder method in your adapter at this point for you to rebind that item with the updated data.

如果该模型不是 Kotlin数据类,则必须确保该类实现了 compareTo 方法.如果不是,则将对象的内存地址与对象的实际内容进行比较.如果是这种情况,由于对象的内存地址未更改,方法 areContentsTheSame 将始终返回true.

If that model is not a Kotlin data class, than you must make sure the class implements the compareTo method. If not, you are comparing the object's memory address vs the actual contents of the object. If that is the case, the method areContentsTheSame will always return true, since the object's memory address has not changed.

这些是一些调试技巧,因为在没有更多有关代码实现方式的知识的情况下,很难提供更清晰的答案.

These are some debugging tips, as it is difficult to provide a clearer answer without more knowledge about how the code has been implemented.

这篇关于PagedListAdapter.submitList()更新现有项目时表现怪异的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆