[英]notifyDataSetChanged() not working on custom RecyclerView adapter
我試圖創建一個recyclerView
來顯示當前狀態欄通知的列表。 我創建了一個自定義適配器( NotiRecyclerAdapter
),該適配器采用NotificationItemInformation
的List
public class NotificationItemInformation
{
int iconId,noitId;
String packageName;
Drawable notiIcon;
}
我正在使用SQLite數據庫存儲所有通知。 每當發布或刪除通知時, NotificationListenerService
都會從數據庫中寫入和刪除。
我使用一種稱為
public List<NotificationItemInformation> ReadNotilist (Context context);
(位於myDBHelper內部)將DB的內容讀取到NotificationItemInformation
List
,該List
稱為data
(在我的Main Activity中是global,public和static)。 然后我使用adapter
(在Main Activity中也是global,public和static)來獲取data
並將其設置到MainActivity
的onCreate
方法內的RecyclerView
。
到目前為止,一切工作正常。 我可以看到RecyclerView
填充了當前的StatusBar
通知。
問題是,直到我重新啟動活動,列表才會更新(如果有新的通知到來)。 我嘗試打電話給...
MainActivity.data.clear();
MainActivity.data = dbh.ReadNotilist(this); // dbh is DBhelper object
MainActivity.adapter.notifyDataSetChanged();
...在我的NotificationListenerService
onNotificationPosted
(添加到數據庫中之后)。 但是,直到我重新啟動活動, RecyclerView
仍不會得到更新。
如果您想看一下,這是我的MainActivity
。
public class MainActivity extends AppCompatActivity
{
SQLiteDatabase db;
DBHelper dbh;
RecyclerView notificationIconRecyclerView;
public static NotiRecyclerAdapter adapter;
public static List<NotificationItemInformation> data = Collections.EMPTY_LIST;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
dbh = new DBHelper(this);
db = dbh.getDb();
notificationIconRecyclerView = (RecyclerView) findViewById(R.id.notificationIconRecyclerView);
data = dbh.ReadNotilist(this);
adapter = new NotiRecyclerAdapter(this,data);
notificationIconRecyclerView.setAdapter(adapter);
notificationIconRecyclerView.setLayoutManager(new LinearLayoutManager(this,LinearLayoutManager.HORIZONTAL,true));
}
}
這是我為RecyclerView
定制的適配器
public class NotiRecyclerAdapter extends RecyclerView.Adapter<NotiRecyclerAdapter.MyViewHolder>
{
private LayoutInflater inflater;
List<NotificationItemInformation> data = Collections.emptyList();
NotiRecyclerAdapter(Context context, List<NotificationItemInformation> data)
{
inflater = LayoutInflater.from(context);
this.data = data;
}
@Override
public void registerAdapterDataObserver(RecyclerView.AdapterDataObserver observer)
{
super.registerAdapterDataObserver(observer);
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
{
View view = inflater.inflate(R.layout.custom_recyclerview_item,parent,false);
MyViewHolder holder = new MyViewHolder(view);
return holder;
}
@Override
public void onBindViewHolder(MyViewHolder holder, int position)
{
NotificationItemInformation current = data.get(position);
holder.recyclerItemIcon.setImageDrawable(current.notiIcon);
}
@Override
public int getItemCount()
{
return data.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder
{
ImageView recyclerItemIcon;
public MyViewHolder(View itemView)
{
super(itemView);
recyclerItemIcon = itemView.findViewById(R.id.notiRecyclerItemIcon);
}
}
}
不要重置對數據對象的引用。 而是嘗試這樣的事情:
MainActivity.data.clear();
MainActivity.data.addAll(dbh.ReadNotilist(this));
MainActivity.adapter.notifyDataSetChanged();
在適配器的構造函數中,您編寫
this.data = data;
這會將傳遞給構造函數的List<NotificationItemInformation>
分配給適配器的data
字段。 您的適配器的結構如下:
adapter = new NotiRecyclerAdapter(this,data);
這意味着您的MainActivity.data
字段和adapter.data
字段都引用同一列表。
稍后您寫:
MainActivity.data.clear();
MainActivity.data = dbh.ReadNotilist(this);
MainActivity.adapter.notifyDataSetChanged();
第一行清除MainActivity.data
和 adapter.data
(請記住,由於適配器的構造方式,它們是相同的列表)。 第二行將新列表分配給MainActivity.data
,但不以任何方式影響adapter.data
。 第三行通知適配器數據集已更改(數據集已更改;數據集已清除),但是適配器不會從dbh.ReadNotilist()
“看到”新信息。
AChez9的答案之所以有效,是因為使用addAll()
而不是賦值( =
)意味着MainActivity.data
和adapter.data
仍指向同一List
,因此適配器將“查看”新信息。
這就是為什么當您從外部來源接受列表副本時通常正確的做法。 換句話說,您的適配器的構造函數可能想要這樣做:
this.data = new ArrayList<>(data);
這意味着從傳遞給它的列表更改(在本例中為MainActivity.data
)中,它是“安全的”。 但這意味着您還需要公開一種活動來正確更新適配器。 我建議這樣的方法:
public void updateData(List< NotificationItemInformation> data) {
this.data = new ArrayList<>(data);
notifyDataSetChanged();
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.