【问题标题】:Why notifyItemChanged(position) not updating all the items in RecyclerView?为什么 notifyItemChanged(position) 不更新 RecyclerView 中的所有项目?
【发布时间】:2021-08-23 23:17:54
【问题描述】:

在从 firebase 数据库中获取某些值后,我正在尝试在 recyclerview 中同时更新 3 个项目。下面的方法对 ArrayList itemname 进行三次迭代,每个值都调用 SecurityAlertSensor(itemname) 方法。

在每次迭代的此方法中,回收器视图中的相应项目应更改。就像如果从 SQLite DB 获取的 id 是 1,那么回收器视图的第一项将被更新,并且在下一次迭代中,如果 id 是 2,那么第二项将针对第 3 项进行类似更新。

但是使用下面的代码,只有回收器视图的三项中的最后一项正在更新前两项,这不起作用。

for (int i=0; i<itemname.size(); i++) {
        if (isOnline()) {
            SecurityAlertSensor(itemname.get(i));
        }
        else if(!isOnline())
            Toast.makeText(getApplicationContext(), "Update Failed!", Toast.LENGTH_SHORT).show();
    }

此方法在每次迭代时从 Firebase DB 获取值,如果值为“1”,则调用 notifyItemChanged(position) 以更新 recyclerview 中的特定项目。

private void SecurityAlertSensor(final String email) {
        sec_ref2 = sec_ref1.child(email);
        sec_ref2.addValueEventListener(new ValueEventListener() {
            int id;
            @SuppressLint("SetTextI18n")
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot)
            {
             String value = dataSnapshot.getValue(String.class);
             if (value != null)
             {
                 if (value.contains("0") || value.contains("1"))
                 {
                     Toast.makeText(Security.this, value, Toast.LENGTH_SHORT).show();
                     String[] tokens = value.split(",");
                     power_state = tokens[0];
                     ContentValues values = new ContentValues();
                     values.put(SecurityDatabaseContract.UserDatabase2.SEC_NAME_COL4, tokens[0]);
                     values.put(SecurityDatabaseContract.UserDatabase2.SEC_NAME_COL5, tokens[1]);
                     SecDB.update(SecurityDatabaseContract.UserDatabase2.TABLE_NAME2, values, "address='" + email + "'", null);

                     String query = "SELECT id FROM sec_table WHERE address='"+email+"'";
                     Cursor c1 = SecDB.rawQuery(query,null);

                     if (c1 != null && c1.getCount() != 0)
                     {
                         while (c1.moveToNext()) {
                             id = c1.getInt(c1.getColumnIndex("id"));
                         }
                            c1.close();
                     }

                     if (tokens[1].equals("1")) {
                         alert_position = id;
                         userAdapter.notifyItemChanged(alert_position);
                     }
                 }
                 sec_ref2.removeEventListener(this);
             }
                else
                        Toast.makeText(Security.this, "Device Not Found!", Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onCancelled(@NonNull DatabaseError error) {
                Toast.makeText(getApplicationContext(), "Not Found!", Toast.LENGTH_LONG).show();  // Failed to read value
            }
        });
}

在 Recyclerview Adapter 类的 onBindViewHolder 方法中。每次在主类中实例化 notifyItemChanged(position) 时都会调用它。

public void onBindViewHolder(@NonNull final UserViewHolder holder, final int position) {
 if(position == Security.alert_position) {
            holder.state.setText("< Activated >");
            holder.state.setTextColor(Color.RED);
            holder.cards.setBackgroundColor(0x33FF0000);
        }
}

【问题讨论】:

    标签: javascript android firebase android-recyclerview listadapter


    【解决方案1】:

    你的问题在onBindViewHolder():

    if(position == Security.alert_position) {
    

    您依赖于在每次迭代中将Security.alert_position 的值设置为项目位置。我猜对notifyItemChanged() 的每次调用都不会立即对onBindViewHolder() 进行调用,但是对onBindViewHolder() 的调用是异步的,并且会在以后发生。此时Security.alert_position已经设置为第三个值,所以每次输入onBindViewHolder()时,Security.alert_position的值就是你设置的最后一个值。

    您可以添加一些调试日志来验证我的假设。一般来说,您的架构并不好,因为您在另一个地方做某事时依赖于存储在一个地方的状态。

    【讨论】:

    • 感谢大卫的建议。但是,为什么在通过 Volley 从 MySQL 获取相同数据时,同样的技巧会起作用(所有三个项目都在正确更新)?另外,您能否为此提出一些解决方法?
    • 我不太了解 Volley 的工作原理,无法回答这个问题,抱歉。解决方法?从您发布的代码中,我对您在这里尝试做的事情知之甚少。不过,通常这种架构是错误的。
    猜你喜欢
    • 2017-01-13
    • 2021-08-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-22
    • 2019-02-08
    • 1970-01-01
    相关资源
    最近更新 更多