我正在尝试创建一个显示当前状态栏通知列表的recyclerView
。我创建了一个自定义适配器(NotiRecyclerAdapter
),其List
NotificationItemInformation
public class NotificationItemInformation
{
int iconId,noitId;
String packageName;
Drawable notiIcon;
}
我使用SQLite DB来存储所有通知。
无论何时发布或删除通知,NotificationListenerService
都会从数据库中写入和删除。
我使用名为
的方法public List<NotificationItemInformation> ReadNotilist (Context context);
(在myDBHelper中)将DB的内容读取到名为List
NotificationItemInformation
data
的{{1}}(在我的主要活动中是全局的,公共的和静态的)。
然后我使用adapter
(在我的主要活动中也是全局的,公共的和静态的)来取data
并将其设置为我RecyclerView
方法中的onCreate
MainActivity
。
到目前为止一切运作良好。我可以看到填充了当前RecyclerView
通知的StatusBar
。
问题是列表不会更新(如果有新通知),直到我重新启动活动。我试着打电话......
MainActivity.data.clear();
MainActivity.data = dbh.ReadNotilist(this); // dbh is DBhelper object
MainActivity.adapter.notifyDataSetChanged();
...我的onNotificationPosted
内NotificationListenerService
(在添加到数据库之后)。但是在我重新开始活动之前,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);
}
}
}
答案 0 :(得分:0)
不要重置对数据对象的引用。而是尝试这样的事情:
MainActivity.data.clear();
MainActivity.data.addAll(dbh.ReadNotilist(this));
MainActivity.adapter.notifyDataSetChanged();
答案 1 :(得分:0)
在适配器的构造函数中,编写
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
。第三行通知适配器数据集已更改(它已更改;已清除),但您的适配器不会&#34;&#34;&#34;来自dbh.ReadNotilist()
的新信息。
AChez9的答案有效,因为使用addAll()
代替分配(=
)意味着MainActivity.data
和adapter.data
仍指向同一List
},所以适配器将&#34;看&#34;新信息。
这就是为什么当您从外部来源接受列表时,创建列表的副本通常是正确的。换句话说,适配器的构造函数可能希望这样做:
this.data = new ArrayList<>(data);
这意味着它是安全的&#34;从更改传递给它的列表(在这种情况下,MainActivity.data
)。但这意味着您还需要为您的活动提供一种正确更新适配器的方法。我建议使用这样的方法:
public void updateData(List< NotificationItemInformation> data) {
this.data = new ArrayList<>(data);
notifyDataSetChanged();
}