本文主要闡述在使用RecyclerView中遇到notifyDataSetChanged列表不刷新問題,表現是:列表滑動時,notifyDataSetChanged可以正常刷新界面,但Fragment切換Tab后,再次滑動RecycleView,列表不刷新。
通過打斷點調試,發現數據請求沒有問題,每次滑動到底部時自動請求數據,在數據集上添加網絡數據,通過打斷點信息可得到size由20變為40,數據沒有問題:
通過打斷點調試,發現數據請求沒有問題,每次滑動到底部時自動請求數據,在數據集上添加網絡數據,通過打斷點信息可得到size由20變為40,數據沒有問題:
先看下notifyDataSetChanged實現:
public final void notifyDataSetChanged() {
mObservable.notifyChanged();
}
123
比較明顯,觀察者模式實現,數據改變了,通知觀察者刷新。如果不刷新了,有幾個懷疑點:
1:數據地址變了,不是同一個對象
打個比方:在數據A上注冊了觀察者,后面我們更改了數據B,然后調用了notify,此時必然列表不更新,常見的問題及解決辦法:
list = data;
notifyDataSetChanged;
12
改為
list.clear();
list.addAll(data);
notifyDataSetChanged;
123
2:recycleview地址變了,不是同一個對象
情況類似1,只是由數據換成了recycleview,觀察者不是同一個了,此時notify,更新的不是當前recycleView實例,因此必然看不到界面刷新。
此問題需要結合業務去看,主要通過打斷點去看,notifyDataSetChanged時是否是同一個對象
3:數據和recycleview都是同一個地址,但綁定關系不在了
打個比方,數據A上注冊了recycleview R,然后經過其他操作(如切換ntab),在切換tab聲明周期中,無意間調用了unregisterAdapterDataObserver,導致A和R的綁定關系不在了,因此R不再刷新,
本次遇到的問題正好是情況3,單步調試下看下結果:
public final void notifyDataSetChanged() {
mObservable.notifyChanged();
}
123
比較明顯,觀察者模式實現,數據改變了,通知觀察者刷新。如果不刷新了,有幾個懷疑點:
1:數據地址變了,不是同一個對象
打個比方:在數據A上注冊了觀察者,后面我們更改了數據B,然后調用了notify,此時必然列表不更新,常見的問題及解決辦法:
list = data;
notifyDataSetChanged;
12
改為
list.clear();
list.addAll(data);
notifyDataSetChanged;
123
2:recycleview地址變了,不是同一個對象
情況類似1,只是由數據換成了recycleview,觀察者不是同一個了,此時notify,更新的不是當前recycleView實例,因此必然看不到界面刷新。
此問題需要結合業務去看,主要通過打斷點去看,notifyDataSetChanged時是否是同一個對象
3:數據和recycleview都是同一個地址,但綁定關系不在了
打個比方,數據A上注冊了recycleview R,然后經過其他操作(如切換ntab),在切換tab聲明周期中,無意間調用了unregisterAdapterDataObserver,導致A和R的綁定關系不在了,因此R不再刷新,
本次遇到的問題正好是情況3,單步調試下看下結果:
recyclerView和dataSource地址都沒變(主要看@后面的數字),然后再notifyDataSetChanged處加斷點,看內部執行情況,發現:
觀察者的List為空了,按照猜測,肯定是無意間調用了unregisterAdapterDataObserver,導致數據和RecycleView綁定關系不在了,因此在unregisterAdapterDataObserver處打斷點:
發現在封裝時,在onDetachedFromWindow中無意間調用了unregisterAdapterDataObserver,問題根源已找到,解決辦法:
unregisterAdapterDataObserver調用可以用標志位來控制,業務在使用封裝的recycleview時,復寫此標志位,用來控制是否unregister,這個地方需小心Recycleview的泄漏問題。
————————————————
版權聲明:本文為CSDN博主「longlong2015」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/longlong2015/java/article/details/88826057
unregisterAdapterDataObserver調用可以用標志位來控制,業務在使用封裝的recycleview時,復寫此標志位,用來控制是否unregister,這個地方需小心Recycleview的泄漏問題。
————————————————
版權聲明:本文為CSDN博主「longlong2015」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/longlong2015/java/article/details/88826057