I have a FirebaseRecyclerAdapter displaying a list of objects with their states.
I click the arrow on the right and open an AlertDialog fragment where I can change the state of each item (check/uncheck the item).
The results from the AlertDialog fragment get sent back to the activity that contains the recyclerview by implementing an interface from the DialogFragment:
@Override
public void onDialogPositiveClick(Bundle bundle) {
Hour hour = bundle.getParcelable("hour");
mDatabase.child(protocolKey).child(String.valueOf(hour.getMilitaryHour())).setValue(hour);
mProtocolAdapter.notifyDataSetChanged();
}
The data coming back from the Dialog Fragment is correct - the hour object in onDialogPositiveClick DOES SHOW THE CORRECT DATA WITH THE UPDATES THAT WERE MADE IN THE DIALOGFRAGMENT. AND THE DATA GETS UPDATED CORRECTLY IN THE DATABASE. However, the notifyDataSetChanged does not correctly update the list with their states.
I had a similar issue in another part of the project (currently stripped out to isolate things down to the current issue) and it turned out to be caused by a combination of using a listener and the views getting recycled. I'm guessing this is a similar instance but that fix (setting the listener to null first) is not working here.
Activity with Recyclerview:
public class DailyScheduleActivity2 extends AppCompatActivity implements HourlyTaskDialogFragment.HourlyTaskDialogListener {
private DatabaseReference mDatabase;
private RecyclerView mProtocolRv;
private String protocolKey;
private ProtocolRecyclerViewAdapter mProtocolAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_daily_schedule);
protocolKey = "daily/" + FirebaseAuth.getInstance().getCurrentUser().getUid() + "_" + new LocalDate();
mDatabase = FirebaseDatabase.getInstance().getReference();
Query query = mDatabase.child(protocolKey);
FirebaseRecyclerOptions<Hour> options =
new FirebaseRecyclerOptions.Builder<Hour>()
.setQuery(query, Hour.class)
.build();
mProtocolRv = findViewById(R.id.rv_protocol);
mProtocolRv.setHasFixedSize(false);
LinearLayoutManager mLayoutManager = new LinearLayoutManager(this);
mProtocolRv.setLayoutManager(mLayoutManager);
mProtocolAdapter = new ProtocolRecyclerViewAdapter(this, mDatabase, protocolKey, options);
mProtocolRv.setAdapter(mProtocolAdapter);
}
public static class ProtocolRecyclerViewAdapter extends FirebaseRecyclerAdapter<Hour, ProtocolRecyclerViewAdapter.HourHolder> {
private final DailyScheduleActivity2 mParentActivity;
ProtocolRecyclerViewAdapter(DailyScheduleActivity2 parent, DatabaseReference db, String protocolKey, FirebaseRecyclerOptions<Hour> options) {
super(options);
mParentActivity = parent;
}
@NonNull
@Override
public HourHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.rv_protocol_row2, parent, false);
return new HourHolder(view);
}
@Override
public void onBindViewHolder(@NonNull HourHolder holder, int position, final Hour currentHour) {
holder.mHourCheckBox.setText(currentHour.toString());
//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.mOpenTasks.setOnClickListener(null);
holder.mOpenTasks.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
DialogFragment hourlyTasksFragment = new HourlyTaskDialogFragment().newInstance(currentHour);
hourlyTasksFragment.show(mParentActivity.getSupportFragmentManager(), "HourlyTasks");
}
});
}
class HourHolder extends RecyclerView.ViewHolder {
final TextView mHourCheckBox;
final ImageView mOpenTasks;
final TextView mHour;
HourHolder(View view) {
super(view);
mHourCheckBox = (TextView) view.findViewById(R.id.cb_hour_all);
mOpenTasks = (ImageView) view.findViewById(R.id.open_tasks);
mHour = (TextView) view.findViewById(R.id.hour);
}
}
}
@Override
public void onDialogPositiveClick(Bundle bundle) {
Hour hour = bundle.getParcelable("hour");
mDatabase.child(protocolKey).child(String.valueOf(hour.getMilitaryHour())).setValue(hour);
mProtocolAdapter.notifyDataSetChanged();
}
@Override
protected void onStart() {
super.onStart();
mProtocolAdapter.startListening();
}
@Override
protected void onStop() {
super.onStop();
mProtocolAdapter.stopListening();
}
}