Android 为什么RecyclerView的notifyItemChanged(int位置)只能工作一次而不是三次?

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

我试图复制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='"+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);
            }
        }