Associate data with Snackbar
Closed this issue · 1 comments
I am showing a snackbar when I delete remove something from my RecyclerView so the user can choose to "Undo" the deletion like in Gmail but what I am struggling with is how to associate data with a snackbar.
For example the user clicks on the undo I will just call notifyDatasetChanged on the adapter to bring back all the data again which is fine but the problem is when I want to delete that entry for good. Since onDismiss
gets called no matter what how do I know weather its being dismissed from an action click or the snackbar time out/dismissal
For my project, I handled this by creating a new ArrayList
and adding the elements from the main ArrayList
that are to be deleted. I keep their locations in a SparseBooleanArray
. So, delete them and notifyItemRemoved
on each so they animate out. Then, in the Snackbar onActionClicked
, I add them back to the main ArrayList
then notifyItemInserted
on each, which animates them back into place. Avoid notifyDatasetChanged
whenever possible; it'll kill your animations.
Here's my code:
case R.id.action_delete:
//Save the characters and positions temporarily in case the user wants to undo the delete
final ArrayList<GameCharacter> storedCharacters = new ArrayList<>();
final SparseBooleanArray storedPositions = selectedItems.clone(); //Creating a copy of the positions was necessary because other parts of my code could clear selectedItems before the Snackbar finished
for(int i = 0; i<storedPositions.size(); i++){
storedCharacters.add(gameCharacterList.get(storedPositions.keyAt(i)));
}
//Delete the characters
for (int i = selectedItems.size() - 1; i >= 0; i--) {
gameCharacterList.remove(selectedItems.keyAt(i));
recyclerViewAdapter.notifyItemRemoved(selectedItems.keyAt(i));
}
selectedItems.clear();
resetDefaultMenu(); //I'm using a gmail-like functionality that changes the toolbar and statusbar to grey while items have been selected. This restores the normal colors and resets the menu action items
//Allow the user to undo delete
SnackbarManager.show(
Snackbar.with(getApplicationContext())
.text(getString(R.string.deleted_count, storedPositions.size())) // text to display
.actionLabel(getString(R.string.undo))
.actionColor(getResources().getColor(R.color.accent))
.actionListener(new ActionClickListener() {
@Override
public void onActionClicked(Snackbar snackbar) {
//User clicked UNDO, so add the stored characters back in their original positions
for (int i = 0; i < storedPositions.size(); i++) {
gameCharacterList.add(storedPositions.keyAt(i), storedCharacters.get(i));
recyclerViewAdapter.notifyItemInserted(storedPositions.keyAt(i));
}
}
}), this);
break;
Hope this helps.