Android 为什么RecyclerView的notifyItemChanged(int位置)只能工作一次而不是三次?
我试图复制Recyclerview方法的操作,其中ArrayList itemname中有3个项,并且还存储在sqlite表中。表中为每个项目名称分配了一个“id”。在这里,我希望对于下面的每一次迭代,所有3项都将根据适配器类的onBindViewHolder()方法中定义的条件更改颜色Android 为什么RecyclerView的notifyItemChanged(int位置)只能工作一次而不是三次?,android,android-recyclerview,android-volley,notifydatasetchanged,Android,Android Recyclerview,Android Volley,Notifydatasetchanged,我试图复制Recyclerview方法的操作,其中ArrayList itemname中有3个项,并且还存储在sqlite表中。表中为每个项目名称分配了一个“id”。在这里,我希望对于下面的每一次迭代,所有3项都将根据适配器类的onBindViewHolder()方法中定义的条件更改颜色 for (int i=0; i<itemname.size(); i++) { String query = "SELECT id FROM sec_table WHERE address
for (int i=0; i<itemname.size(); i++) {
String query = "SELECT id FROM sec_table WHERE address='"+itemname.get(i)+"'";
Cursor c1 = SecDB.rawQuery(query,null);
if (c1 != null && c1.getCount() != 0)
{
while (c1.moveToNext()) {
id = c1.getInt(c1.getColumnIndex("id"));
}
c1.close();
}
alert_position = id; // Class variable 'alert_position'
userAdapter.notifyItemChanged(alert_position);
}
for (int i=0; i<Security.alert_position.size(); i++) {
if (position == Security.alert_position.get(i)) {
holder.state.setText("< Data Changed >");
holder.state.setTextColor(Color.RED);
holder.cards.setBackgroundColor(0x33FF0000);
}
}
for(int i=0;i对notifyItemChanged()
的调用是不同步的,即onBindViewHolder()
稍后将被调用。调用onBindViewHolder()
时,静态属性Security.alert\u position
包含最新值(从第三次循环开始)
建议:
将日志语句添加到对notifyItemChanged()
和onBindViewHolder()
的调用中。您可能会看到notifyItemChanged()
调用先于对onBindViewHolder()
的调用。在onBindViewHolder()中记录位置和Security.alert\u position
值
,这应该可以解释你为什么看到你看到的东西
Log.d("MY-TAG", String.format("calling notifyItemChanged(%d)", alert_position));
onBindViewHolder()中的
我怀疑您会看到对onBindViewHolder()
的三个调用显示了正确的位置值(1,2,3),但是Security.alert\u position
始终是3
虽然此建议无法解决您的程序逻辑,但它有望帮助您了解发生了什么
我会使用ListAdapter
(来自RecyclerView)
在游标迭代期间,我将基于新值创建(或修改)一个新列表
然后我会向适配器提交一个新列表(ListAdapter有一个名为submitList(T)
)的方法
由于您需要向ListAdapter提供一个“Diff Util”回调,它将负责重新绑定数据已更改的视图
如果您真的希望一个接一个地进行“实时”更改,那么您需要更深入地让ViewModel公开一个状态(可能是一个流
),您可以观察并对每个发射(…)
做出反应
这里有其他选择,但我会首先尝试ListAdapter,它包含在Android中,可能工作得很好
如果您需要帮助设置列表适配器,并且因为我已经被问了9000多次这个问题,我已经创建了我可以想象的:)得到了解决方案。同样可以通过向Arraylist添加位置,然后通过Recyclerview适配器类中的for循环通过迭代进一步调用该Arraylist来实现
if (tokens[0].equals("1")) {
power_position.add(id);
userAdapter.notifyDataSetChanged();
}
在Recyclerview适配器类中
for (int i=0; i<itemname.size(); i++) {
String query = "SELECT id FROM sec_table WHERE address='"+itemname.get(i)+"'";
Cursor c1 = SecDB.rawQuery(query,null);
if (c1 != null && c1.getCount() != 0)
{
while (c1.moveToNext()) {
id = c1.getInt(c1.getColumnIndex("id"));
}
c1.close();
}
alert_position = id; // Class variable 'alert_position'
userAdapter.notifyItemChanged(alert_position);
}
for (int i=0; i<Security.alert_position.size(); i++) {
if (position == Security.alert_position.get(i)) {
holder.state.setText("< Data Changed >");
holder.state.setTextColor(Color.RED);
holder.cards.setBackgroundColor(0x33FF0000);
}
}
用于(int i=0;我会这么说的。你没有在这里使用列表视图,对吗?我已经删除了它的标签,似乎你在使用回收器Hanks来指出,但是为什么同样的方法通过截击方法工作得很好?另外,你能建议一些解决方法,我可以同时刷新所有3张卡,而不是只刷新最后一张卡。虽然“截击”方法似乎工作正常,但现在我换成了Firebase。@Jennifer,我还不是100%清楚你想完成什么。你可以使用notifyDataSetChanged()
而不是notifyItemChanged()强制整个RecyclerView
重新加载
,这将重新创建和绑定所有视图,其position==Security.alert\u position
的项目将被涂成红色。关于截击方法,我没有看到循环,只有一个notifyItemChanged()
call,因此Security.alert\u position
将有一个可预测的值。建议的日志记录将帮助您更好地了解正在发生的事情。好吧,我有一个Recyclerview,通过从MySQL/Firebase获取数据来扩展它。每个卡都代表一个无线传感器,具有特定的DB名称标签。此传感器被获取并存储在SQLite local DB中,具有相应的id。为了持续监控传感器的在线状态,通过截取查询MySQL,如果从数据库接收到值“1”,则该传感器的卡将变为红色。如果所有3个传感器都打开,则它们必须变为红色。此处为notifyDataSetChanged()也只将最后一张牌变为红色。通过for loop.for(int i=0;IAlThrough Firebase onDataSetChange()调用volley方法方法是实时将卡变为红色,即传感器状态发生变化且传感器活动类或Recyclerview在屏幕上打开时,但当传感器已激活且传感器活动启动时,则只会出现最后一张卡变为红色的问题。
for (int i=0; i<Security.alert_position.size(); i++) {
if (position == Security.alert_position.get(i)) {
holder.state.setText("< Data Changed >");
holder.state.setTextColor(Color.RED);
holder.cards.setBackgroundColor(0x33FF0000);
}
}