I bind a recyclerView
to FirebaseRecyclerAdapter
, and set OnClickListener
for checkboxes in ViewHolder
.
My idea:
When a checkbox of a row is checked, the adapter will getRef(clickedPosition)
and call removeValue
to delete the row from Firebase database. After that, the populateViewHolder
is called and the application will show the latest data from the database.
Problem:
If I delete from the bottom of the list upwards, there is no problem.
However, if randomly check checkboxes, seems the wrong row will be deleted, and sometimes even will have NULL
position and cause the Android app crash.
I have Log the position, seems the position of checkboxes is not updated correctly after a row is deleted.
Here is my code:
public Firebase mRef;
// UI
RecyclerView mRecyclerView;
FirebaseRecyclerAdapter<Task, MessageViewHolder> adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my_task);
...
...
Firebase.setAndroidContext(this);
mRef = new Firebase("https://what-to-do-list.firebaseio.com/todoItems");
mRecyclerView = (RecyclerView) findViewById(R.id.recyclerView);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
}
@Override
protected void onStart() {
super.onStart();
adapter =
new FirebaseRecyclerAdapter<Task, MessageViewHolder>(
Task.class,
R.layout.custom_row_view,
MessageViewHolder.class,
mRef
) {
@Override
protected void populateViewHolder(MessageViewHolder messageViewHolder, Task t, int i) {
messageViewHolder.mText.setText(t.getName());
messageViewHolder.chkBox.setTag(i);
messageViewHolder.chkBox.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
CheckBox cb = (CheckBox) v;
int clickedPos = ((Integer) cb.getTag()).intValue();
Log.v("POSITION: ", String.valueOf(clickedPos));
adapter.getRef(clickedPos).removeValue();
}
});
}
};
mRecyclerView.setAdapter(adapter);
}
@JsonIgnoreProperties(ignoreUnknown = true)
public static class MessageViewHolder
extends RecyclerView.ViewHolder {
TextView mText;
CheckBox chkBox;
public MessageViewHolder(View v) {
super(v);
mText = (TextView) v.findViewById(R.id.list_item_name);
chkBox = (CheckBox) v.findViewById(R.id.task_chkbox);
}
}
Change your populateViewHolder to:
@Override
protected void populateViewHolder(MessageViewHolder messageViewHolder, Task t, int i) {
final DatabaseReference ref = getRef(i);
messageViewHolder.mText.setText(t.getName());
messageViewHolder.chkBox.setTag(ref);
messageViewHolder.chkBox.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
CheckBox cb = (CheckBox) v;
String key = cb.getTag().getKey();
adapter.getRef(key).removeValue();
}
});