このトピックの小さな話:アプリは、確認されたときにダイアログでクリックされた行の値を更新するだけです。部屋のデータベースでページ分割シナリオを使用します。
アイテムが追加または削除されると、最新のデータセットがフェッチされ、submitListメソッドに渡されます。その後、すべての変更が表示され、適切に機能します。
問題はそこから始まり、既存のアイテムが更新されると、最新のデータセットが適切にフェッチされてsubmitListに渡されますが、今回は変更されていないようです。
_DIFF_CALLBACK
_をデバッグしてareItemsTheSame
でアイテムをキャッチしたとき、newHistory
とoldHistory
の値は同じです! (どうやって!)
submitList
メソッドにバグがある可能性はありますか?
初期化後、observe
はルームからリストをフェッチしてmHistoryAdapter.submitList(it)
に渡します。次に、アイテムを更新すると、再度トリガーされ、param _it
に更新された値が表示され、submitList
に渡されます。
残念ながら、アダプターは変更されません...
_ mResolvedAddressViewModel = ViewModelProviders.of(this).get(ResolvedAddressViewModel::class.Java)
mResolvedAddressViewModel.getAddresses(false).observe(this, Observer {
mHistoryAdapter.submitList(it)
})
_
すべてのパーツ
型番
_@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)
})
}
}
_
質問には、より詳細な回答を提供するのに役立ついくつかの欠けている点があります。
例あなたのRecyclerView.Adapter
はどのように見えますか? PagedListAdapter
を拡張しますか?
モデルクラスはどのように見えますか? Kotlinデータクラスですか?
答えを提供するために、それらの未知数が私たちが期待するものであると仮定しましょう。
質問を理解した場合、あなたはアイテムをupdating
だけであり、アイテムを削除または追加していないようです。したがって、古いリストと新しいリストのサイズは変更されていないため、DiffUtil.ItemCallback
のareItemsTheSame
は常にtrueを返します。つまり、アイテムを更新した場合は、そのコンテンツが更新され、リストから削除されていない可能性があります。
そのため、IDが同じであるため、areItemsTheSame
はtrueを返します。
アイテムのコンテンツを更新したため、2番目のメソッドareContentsTheSame
はfalseを返す可能性が高くなります。
モデルクラスResolvedAddress
がKotlinデータクラスの場合、古いリストと新しいリストから更新されたアイテムを比較すると、メソッドareContentsTheSame
はfalseを返します。これにより、この時点でアダプターのonBindViewHolder
メソッドがトリガーされ、更新されたデータでそのアイテムを再バインドできます。
そのモデルがKotlin data class
ではない場合は、クラスがcompareTo
メソッドを実装していることを確認する必要があります。そうでない場合は、オブジェクトのメモリアドレスとオブジェクトの実際の内容を比較しています。その場合、オブジェクトのメモリアドレスは変更されていないため、メソッドareContentsTheSame
は常にtrueを返します。
コードがどのように実装されているかについての知識がなければ、より明確な回答を提供することは困難であるため、これらはデバッグのヒントです。
私は同様の問題を抱えていましたが、ここの回答で提案されているように、既存のアイテムを直接更新するのではなく、新しいオブジェクトで既存のアイテムを更新することでなんとか修正しました: