I'm at a loss as to why this is happening. I have a recyclerview listing a set of Hour objects as checkboxes with text.
Couldn't find a way to embed videos. YouTube clip is here: https://www.youtube.com/watch?v=KI9FJSfmrXM
The movie shows a view of my Firebase RealTime Database on the left. Each item corresponds to a checkbox in my app on the right. The keys are the hours of each item in military time. So 8am is 8 and 5pm is 17, etc. When I check/uncheck an item, other items are randomly checked/unchecked also. I'm updating the entire object for that hour:
public static class ProtocolRecyclerViewAdapter extends FirebaseRecyclerAdapter<Hour, ProtocolRecyclerViewAdapter.HourHolder> {
private final DailyScheduleActivity mParentActivity;
private DatabaseReference mDb;
private String protocolUserDateKey;
ProtocolNonMalignant mProtocol = new ProtocolNonMalignant();
ProtocolRecyclerViewAdapter(DailyScheduleActivity parent, DatabaseReference db, String protocolKey, FirebaseRecyclerOptions<Hour> options) {
super(options);
mParentActivity = parent;
mDb = db;
protocolUserDateKey = protocolKey;
}
@NonNull
@Override
public HourHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.rv_protocol_row, parent, false);
return new HourHolder(view);
}
@Override
public void onBindViewHolder(@NonNull HourHolder holder, final int position, final Hour currentHour) {
holder.mHourCheckBox.setText(currentHour.toString());
String state = determineCheckboxState(currentHour);
if (state.equals("unchecked")) {
holder.mHourCheckBox.setChecked(false);
} else if (state.equals("checked")) {
holder.mHourCheckBox.setChecked(true);
}
//https://stackoverflow.com/questions/25646048/how-to-convert-local-time-to-am-pm-time-format-using-jodatime
LocalTime time = new LocalTime(currentHour.getMilitaryHour(), 0);
DateTimeFormatter fmt = DateTimeFormat.forPattern("h:mm a");
holder.mHour.setText(fmt.print(time));
holder.mHourCheckBox.setOnCheckedChangeListener(new CheckBox.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton cb, boolean isChecked) {
cb = (CheckBox) cb;
if (cb.isChecked()) {
currentHour.setState(true);
mDb.child(protocolUserDateKey).child(String.valueOf(currentHour.getMilitaryHour())).setValue(currentHour);
} else {
currentHour.setState(false);
mDb.child(protocolUserDateKey).child(String.valueOf(currentHour.getMilitaryHour())).setValue(currentHour);
}
}
});
}
class HourHolder extends RecyclerView.ViewHolder {
final CheckBox mHourCheckBox;
final ImageView mOpenTasks;
final TextView mHour;
HourHolder(View view) {
super(view);
mHourCheckBox = (CheckBox) view.findViewById(R.id.cb_hour_all);
mOpenTasks = (ImageView) view.findViewById(R.id.open_tasks);
mHour = (TextView) view.findViewById(R.id.hour);
}
}
private String determineCheckboxState(Hour hour) {
boolean allFalse = true;
boolean allTrue = true;
// Check the state of Juice, Meal, and CE.
if (hour.getJuice() != null && hour.getJuice().getState() == true ||
hour.getMeal() != null && hour.getMeal().getState() == true ||
hour.getCe() != null && hour.getCe().getState() == true) {
allFalse = false;
} else {
allTrue = false;
}
// Check the state of the supplements.
ArrayList<Supplement> supplements = hour.getSupplements();
for (int i = 0; i < supplements.size(); i++) {
if (supplements.get(i).getState() == true) {
allFalse = false;
} else {
allTrue = false;
}
}
if (allFalse == true) {
return "unchecked";
} else if (allTrue == true) {
return "checked";
}
}
}
The ".child(String.valueOf(currentHour.getMilitaryHour()))" part should limit the update to only the appropriate hour, no? When I run through things with the debugger, the "currentHour" is always the correct info.
Update: This db update code is inside the Recyclerview FirebaseRecyclerAdapter's onBindViewHolder. And putting a Log.d inside onBindViewHolder logs a message multiple times whenever the random updates occurs. Which means onBindViewHolder is being called multiple times sometimes. But why?