当 RecyclerView 中的项目超过 5 个时,Switch 会更改其行为
Switch changes its behaviour when there are more than 5 items in RecyclerView
我有 recyclerView 显示数据库中的项目列表。在每个项目中,都有一个开关显示值 true
或 false
,具体取决于数据库值。
如果您更改开关状态(例如将其变为 on/off),它将使用当前布尔值更新数据库中的值。问题是什么,当 RecyclerView 中最多有 5 个项目时它运行良好。如果有超过 5 个项目,所有项目的开关都会将其状态更改为 on/randomly 并更新数据库中的行。当我通过仅显示当前状态的 Toast 进行测试时,一切正常。
我在 2 个数据库上进行了测试,结果相同:sqlite3
使用 ContentProviders,现在我迁移到使用 LiveData 的 Room。
这是我在适配器中设置 onCheckedChanged
的方式:
@NonNull
@Override
public AlarmViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = mInflater.inflate(R.layout.alarm_item, parent, false);
return new AlarmViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull AlarmViewHolder holder, int position) {
//get data for current adapter position
Alarms currentData = mAlarms.get(position);
//check if alarm is valid and then set this value to the switch
holder.isAlarmActiveSwitch.setChecked(currentData.isValid());
new validationUpdater().switchChangedListener
(holder.isAlarmActiveSwitch,
context, currentData.get_id());`
}
我创建 validationUpdater()
class 的实例并调用方法 switchChangedListener
,将 holder.isAlarmActiveSwitch
作为 Switch 传递,context
和 id
数据库中的行。
switchChangedListener()
方法:
public void switchChangedListener(@NotNull final Switch switchActive, @NotNull final Context context, final long id) {
switchActive.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(final CompoundButton compoundButton, final boolean b) {
AsyncTask.execute(new Runnable() {
@Override
public void run() {
AlarmDatabase db = AlarmDatabase.getInstance(context);
AlarmsDao dao = db.alarmsDao();
dao.updateAlarm(id, b);
}
});
}
});
}
和来自 Dao 的@Query:
@Query("UPDATE alarm_table SET valid = :valid WHERE _id = :id")
void updateAlarm(final long id, final boolean valid);
任何人都可以向我解释为什么这只在 显示超过 5 个项目后才按预期工作吗?
您的问题是 recyclerview 中的行项目重复覆盖了 getItemViewType 方法,希望这对您有用。
@Override
public int getItemViewType(int position) {
return position;
}
我有 recyclerView 显示数据库中的项目列表。在每个项目中,都有一个开关显示值 true
或 false
,具体取决于数据库值。
如果您更改开关状态(例如将其变为 on/off),它将使用当前布尔值更新数据库中的值。问题是什么,当 RecyclerView 中最多有 5 个项目时它运行良好。如果有超过 5 个项目,所有项目的开关都会将其状态更改为 on/randomly 并更新数据库中的行。当我通过仅显示当前状态的 Toast 进行测试时,一切正常。
我在 2 个数据库上进行了测试,结果相同:sqlite3
使用 ContentProviders,现在我迁移到使用 LiveData 的 Room。
这是我在适配器中设置 onCheckedChanged
的方式:
@NonNull
@Override
public AlarmViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = mInflater.inflate(R.layout.alarm_item, parent, false);
return new AlarmViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull AlarmViewHolder holder, int position) {
//get data for current adapter position
Alarms currentData = mAlarms.get(position);
//check if alarm is valid and then set this value to the switch
holder.isAlarmActiveSwitch.setChecked(currentData.isValid());
new validationUpdater().switchChangedListener
(holder.isAlarmActiveSwitch,
context, currentData.get_id());`
}
我创建 validationUpdater()
class 的实例并调用方法 switchChangedListener
,将 holder.isAlarmActiveSwitch
作为 Switch 传递,context
和 id
数据库中的行。
switchChangedListener()
方法:
public void switchChangedListener(@NotNull final Switch switchActive, @NotNull final Context context, final long id) {
switchActive.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(final CompoundButton compoundButton, final boolean b) {
AsyncTask.execute(new Runnable() {
@Override
public void run() {
AlarmDatabase db = AlarmDatabase.getInstance(context);
AlarmsDao dao = db.alarmsDao();
dao.updateAlarm(id, b);
}
});
}
});
}
和来自 Dao 的@Query:
@Query("UPDATE alarm_table SET valid = :valid WHERE _id = :id")
void updateAlarm(final long id, final boolean valid);
任何人都可以向我解释为什么这只在 显示超过 5 个项目后才按预期工作吗?
您的问题是 recyclerview 中的行项目重复覆盖了 getItemViewType 方法,希望这对您有用。
@Override
public int getItemViewType(int position) {
return position;
}