今天在項目中發(fā)現(xiàn)怎么使用notifyDataSetChanged刷新數(shù)據(jù)都沒用,千看百看,忽然靈感一來,記得以前也有這樣的情況,趕緊記錄在案以防我的笨腦瓜子又忘了。
關(guān)鍵點:notifyDataSetChanged只負(fù)責(zé)對你第一次設(shè)置的數(shù)據(jù)源進(jìn)行“監(jiān)聽”。假如在中途你的數(shù)據(jù)源地址(引用)發(fā)生了改變,再去調(diào)用notifyDataSetChanged將不會生效。
錯誤使用場景(邏輯)
/*createNewData返回新生成的數(shù)據(jù)數(shù)組*/
ArrayList<String> createNewData() {
ArrayList<String> newData = new ArrayList<>();
get data;
return newData;
}
//...
ArrayList<String> mData;
//...
mData = createNewData();
mAdapter = new Adapter(mData);
mRecyclerView.setAdapter(mAdapter);
void onClick {
updateData();
}
void updateData() {
mData = createNewData();
mAdapter.notifyDataSetChanged();
}
在上述情況下,當(dāng)需要重新生成數(shù)據(jù)的時候,再次調(diào)用createNewData,notifyDataSetChanged是不可能起作用的。
因為mData的地址引用的list已經(jīng)不是第一次傳給Adapter的那個mData的引用了。
正確使用場景(邏輯)
/*createNewData返回新生成的數(shù)據(jù)數(shù)組*/
ArrayList<String> createNewData() {
ArrayList<String> newData = new ArrayList<>();
get data;
return newData;
}
//...
ArrayList<String> mData;
//...
mData = new ArrayList<>();
mData.addAll(createNewData());
mAdapter = new Adapter(mData);
mRecyclerView.setAdapter(mAdapter);
void onClick {
updateData();
}
void updateData() {
mData.clear();
mData.addAll(createNewData());
mAdapter.notifyDataSetChanged();
}
而在這種情況下,因為mData的地址已經(jīng)固定,只是對其內(nèi)容進(jìn)行增刪,通過調(diào)用notifyDataSetChanged則可以判斷mData是否發(fā)生了變化從而刷新UI。
DEMO
最后附上demo地址, 簡單展現(xiàn)了這兩種情況。
效果圖