[解決済み] RecyclerViewのListAdapterのアイテムが更新されない
質問
新しいサポートライブラリを使用しています
ListAdapter
. 以下は、私のアダプタのコードです。
class ArtistsAdapter : ListAdapter<Artist, ArtistsAdapter.ViewHolder>(ArtistsDiff()) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
return ViewHolder(parent.inflate(R.layout.item_artist))
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.bind(getItem(position))
}
class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
fun bind(artist: Artist) {
itemView.artistDetails.text = artist.artistAlbums
.plus(" Albums")
.plus(" \u2022 ")
.plus(artist.artistTracks)
.plus(" Tracks")
itemView.artistName.text = artist.artistCover
itemView.artistCoverImage.loadURL(artist.artistCover)
}
}
}
でアダプタを更新しています。
musicViewModel.getAllArtists().observe(this, Observer {
it?.let {
artistAdapter.submitList(it)
}
})
私のdiffクラス
class ArtistsDiff : DiffUtil.ItemCallback<Artist>() {
override fun areItemsTheSame(oldItem: Artist?, newItem: Artist?): Boolean {
return oldItem?.artistId == newItem?.artistId
}
override fun areContentsTheSame(oldItem: Artist?, newItem: Artist?): Boolean {
return oldItem == newItem
}
}
何が起こっているかというと、submitList が最初に呼ばれたとき、アダプタはすべての項目をレンダリングします。しかし、オブジェクトのプロパティを更新して submitList が再度呼ばれたとき、変更されたビューを再レンダリングしません。
リストをスクロールするとビューが再レンダリングされ、その際に
bindView()
また、私は
adapter.notifyDatasSetChanged()
を呼び出すと、更新された値でビューがレンダリングされることに気づきましたが、私は
notifyDataSetChanged()
を呼び出したくありません。なぜなら、リストアダプタには diff ユーティリティが組み込まれているからです。
どなたか教えてください。
どのように解決するのですか?
編集:なぜこのようなことが起こるのか、それは私のポイントではなかったと理解しています。私が言いたいのは、少なくとも警告を出すか、あるいは
notifyDataSetChanged()
関数を呼び出す必要があるということです。なぜなら、どうやら私は
submitList(...)
関数を呼び出しているからです。submitList()が黙って呼び出しを無視することがわかるまで、人々が何時間も何が悪かったのか考えようとしているのは確かです。
これは
Google
の奇妙なロジックのせいです。そのため、同じリストをアダプタに渡しても、アダプタは
DiffUtil
.
public void submitList(final List<T> newList) {
if (newList == mList) {
// nothing to do
return;
}
....
}
私は本当にこの全体のポイントを理解していない
ListAdapter
が同じリストの変更を扱えないのであれば、その意味が分かりません。リスト上の項目を変更したい場合は
ListAdapter
に渡したリストの項目を変更し、その変更を確認したい場合は、 リストの深いコピーを作成するか、あるいは通常の
RecyclerView
を使うか、あるいは自分で
DiffUtill
クラスに変換します。
関連
-
Androidのadbデバイスがオフラインであることが判明
-
Android端末にADBが接続できない!を解決。理由: デバイスが認証されていない!
-
NetworkOnMainThreadException
-
android.os の NetworkOnMainThreadException。
-
デフォルトのアクティビティが見つからない場合の対処法
-
を作ってください。*** makeするルールがない エラーの原因、分析、解決策
-
JVMのエラーに遭遇しました。Java Runtime Environmentによって致命的なエラーが検出されました。
-
エラータイプ 3 タイプエラー, Error: アクティビティクラス{}が存在しません。アクティビティ起動時のエラー 解決方法
-
WeChatとQQは、他のアプリのオープンリストに自分のアプリを追加し、ファイルパスを取得することができます
-
アンドロイドの遅延実行のいくつかの方法
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
AAPT2エラーについて:詳しくはログをご確認ください。
-
NetworkOnMainThreadException
-
aapt2エラー:ログを確認する(具体的な原因の探り方)
-
AndroidStudio reports Could not resolve all artifacts for configuration ':app:classpath'.
-
telnet'が内部コマンドまたは外部コマンドとして認識されない 解決方法
-
Android Nで報告されたエラーを解決する: android.os.FileUriExposedException: file:///storage/emulated/0/
-
Android TextViewにandroid:ellipsize=endのバグがある。
-
WeChatとQQは、他のアプリのオープンリストに自分のアプリを追加し、ファイルパスを取得することができます
-
Android カスタムスピナーコントロールのドロップダウン・ボックスの実装
-
超シンプルなアンドロイドのタイムディレイ機能