Created
January 10, 2016 20:22
-
-
Save jirivrany/f1f177b7bbc187e8f980 to your computer and use it in GitHub Desktop.
Example of undo action for Android RecyclerView onSwipe.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class PhotoAdapter extends RecyclerView.Adapter<PhotoAdapter.PhotoViewHolder> implements View.OnClickListener { | |
private ArrayList<Photo> photos; | |
public ArrayList<Photo> photosToRemove; | |
private OnItemClickListener onItemClickListener; | |
private Context context; | |
public PhotoAdapter(Context context, ArrayList<Photo> photos, Map<Integer, String> authors, int colHeigth) { | |
this.photos = photos; | |
this.context = context; | |
this.photosToRemove = new ArrayList<>(); | |
} | |
public void setOnItemClickListener(OnItemClickListener onItemClickListener) { | |
this.onItemClickListener = onItemClickListener; | |
} | |
@Override | |
public PhotoViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { | |
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_myphotos, parent, false); | |
v.setOnClickListener(this); | |
BusProvider.getInstance().register(this); | |
PhotoViewHolder photoViewHolder = new PhotoViewHolder(v); | |
return photoViewHolder; | |
} | |
@Override | |
public void onBindViewHolder(PhotoViewHolder holder, int position) { | |
Photo photo = photos.get(position); | |
String tempUrl = context.getFilesDir() + UrlBuilder.localCoverPhoto(photo.remoteId); | |
Glide.with(context) | |
.load(tempUrl) | |
.centerCrop() | |
.diskCacheStrategy(DiskCacheStrategy.ALL) | |
.into(holder.photoCover); | |
holder.itemView.setTag(photo); | |
} | |
@Override | |
public void onViewRecycled(PhotoViewHolder holder) { | |
super.onViewRecycled(holder); | |
Glide.clear(holder.photoCover); | |
} | |
@Override | |
public int getItemCount() { | |
return photos.size(); | |
} | |
@Override | |
public void onClick(final View v) { | |
// Give some time to the ripple to finish the effect | |
if (onItemClickListener != null) { | |
new Handler().postDelayed(new Runnable() { | |
@Override public void run() { | |
onItemClickListener.onItemClick(v, (Photo) v.getTag()); | |
} | |
}, 50); | |
} | |
} | |
public void onItemRemove(final RecyclerView.ViewHolder viewHolder, final RecyclerView mRecyclerView) { | |
final int adapterPosition = viewHolder.getAdapterPosition(); | |
final Photo mPhoto = photos.get(adapterPosition); | |
Snackbar snackbar = Snackbar | |
.make(mRecyclerView, context.getString(R.string.removed_from_device), Snackbar.LENGTH_LONG) | |
.setAction(R.string.undo, new View.OnClickListener() { | |
@Override | |
public void onClick(View view) { | |
int mAdapterPosition = viewHolder.getAdapterPosition(); | |
photos.add(mAdapterPosition, mPhoto); | |
notifyItemInserted(mAdapterPosition); | |
mRecyclerView.scrollToPosition(mAdapterPosition); | |
photosToRemove.remove(mPhoto); | |
} | |
}); | |
snackbar.show(); | |
photos.remove(adapterPosition); | |
notifyItemRemoved(adapterPosition); | |
photosToRemove.add(mPhoto); | |
} | |
public static class PhotoViewHolder extends RecyclerView.ViewHolder { | |
ImageView photoCover; | |
public PhotoViewHolder(View itemView) { | |
super(itemView); | |
photoCover = (ImageView) itemView.findViewById(R.id.catalog_photo_cover); | |
} | |
} | |
public interface OnItemClickListener { | |
void onItemClick(View view, Photo photo); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class PhotoFragment extends Fragment implements PhotoAdapter.OnItemClickListener { | |
public static final String TAG = "PhotoFragment"; | |
private int colsNr; | |
private ArrayList<Photo> photos; | |
PhotoAdapter mAdapter; | |
@Bind(R.id.catalog_rv) | |
RecyclerView recyclerView; | |
@Bind(R.id.catalog_empty_view) | |
LinearLayout emptyView; | |
public static PhotoFragment newInstance() { | |
PhotoFragment fragment = new PhotoFragment(); | |
return fragment; | |
} | |
@Override | |
public void onCreate(Bundle savedInstanceState) { | |
super.onCreate(savedInstanceState); | |
colsNr = getResources().getInteger(R.integer.main_grid_columns); | |
} | |
@Nullable | |
@Override | |
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { | |
super.onCreateView(inflater, container, savedInstanceState); | |
View view = inflater.inflate(R.layout.fragment_store_main, container, false); | |
ButterKnife.bind(this, view); | |
GridLayoutManager gridLayoutManager = new GridLayoutManager(getContext(), colsNr); | |
recyclerView.setLayoutManager(gridLayoutManager); | |
return view; | |
} | |
@Override | |
public void onResume() { | |
super.onResume(); | |
photos = (ArrayList<Photo>) Photo.getAllDownloaded(); | |
refreshAdapter(); | |
if (photos.isEmpty()) { | |
showEmptyView(); | |
} | |
else { | |
hideEmptyView(); | |
mAdapter = new PhotoAdapter(getContext(), photos, authorIndex, colHeigth); | |
mAdapter.setOnItemClickListener(this); | |
recyclerView.swapAdapter(mAdapter, false); | |
ItemTouchHelper.Callback callback = new PhotoTouchHelper(mAdapter, recyclerView); | |
ItemTouchHelper helper = new ItemTouchHelper(callback); | |
helper.attachToRecyclerView(recyclerView); | |
} | |
} | |
@Override | |
public void onPause() { | |
ArrayList<Integer> photoIds = new ArrayList<>(); | |
if (mAdapter != null) { | |
if (mAdapter.photosToRemove != null) { | |
for (Photo photo: mAdapter.photosToRemove){ | |
photoIds.add(photo.remoteId); | |
} | |
Intent mServiceIntent = new Intent(getActivity(), PhotoRemoveService.class); | |
mServiceIntent.putExtra(Constants.ARG_GUIDES_TO_DELETE, photoIds); | |
getActivity().startService(mServiceIntent); | |
} | |
} | |
super.onPause(); | |
} | |
private void showEmptyView() { | |
recyclerView.setVisibility(View.GONE); | |
emptyView.setVisibility(View.VISIBLE); | |
} | |
private void hideEmptyView() { | |
recyclerView.setVisibility(View.VISIBLE); | |
emptyView.setVisibility(View.GONE); | |
} | |
@Subscribe | |
public void onEmptyPhotos(MyPhotosEmptyEvent event) { | |
Log.d(TAG, "list is empty"); | |
showEmptyView(); | |
} | |
@Override | |
public void onItemClick(View view, Photo photo) { | |
//@TODO do some action | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class PhotoTouchHelper extends ItemTouchHelper.SimpleCallback { | |
private PhotoAdapter mAdapter; | |
private RecyclerView mRecyclerView; | |
public GuideTouchHelper(PhotoAdapter adapter, RecyclerView recyclerView){ | |
super(ItemTouchHelper.UP | ItemTouchHelper.DOWN, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT); | |
this.mAdapter = adapter; | |
mRecyclerView = recyclerView; | |
} | |
@Override | |
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) { | |
return true; | |
} | |
@Override | |
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) { | |
mAdapter.onItemRemove(viewHolder, mRecyclerView); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
int mAdapterPosition = viewHolder.getAdapterPosition();
return always -1. I've used the previous int istead.final int adapterPosition = viewHolder.getAdapterPosition();
So, my code is:
.... public void onClick(View view) { productsList.add(adapterPosition, mPhoto); notifyItemInserted(adapterPosition); recyclerView.scrollToPosition(adapterPosition); productsRem.remove(mPhoto); }
The UNDO function now is fine