make - Android: desliza para eliminar RecyclerView
recyclerview dependency (3)
Estoy intentando implementar Swipe para eliminar lo mismo que la aplicación de Gmail "Swipe to archive":
He probado muchos tutoriales, pero ninguno de ellos funciona tan rápido como Gmail, prefiero no trabajar en una biblioteca externa. ¿Cómo puedo hacerlo?
Editar:
Mi código hasta ahora-
ItemTouchHelper.SimpleCallback simpleItemTouchCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {
public boolean onMove(RecyclerView recyclerView,
RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
// final int fromPos = viewHolder.getAdapterPosition();
// final int toPos = viewHolder.getAdapterPosition();
// // move item in `fromPos` to `toPos` in adapter.
return true;// true if moved, false otherwise
}
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int swipeDir) {
//Remove swiped item from list and notify the RecyclerView
mAdapter.notifyItemRemoved(viewHolder.getLayoutPosition());
}
};
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(simpleItemTouchCallback);
itemTouchHelper.attachToRecyclerView(mRecyclerView);
Me las arreglé para habilitar el gesto de deslizar, pero no sé cómo agregar un fondo y una imagen debajo de viewHolder . Intenté colocar otro FrameLayout en el archivo item_XXX.xml pero al deslizarlo arroja todo el elemento con el fondo.
Esto definitivamente funcionará. Si quieres un snack bar, usa coordinatorLayout en tu xml. Puede configurar el fondo como gmail. Si tiene alguna acción, simplemente haga clic en el enlace
https://drive.google.com/open?id=11ZOrjMMSjdskt8gG8RP52V5Al5yE50dD
ItemTouchHelper.SimpleCallback simpleItemTouchCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT)
{
Drawable background;
Drawable xMark;
int xMarkMargin;
boolean initiated;
private void init() {
background = new ColorDrawable(Color.RED);
xMark = ContextCompat.getDrawable(Activity.this, R.drawable.ic_delete_svg);
xMark.setColorFilter(Color.WHITE, PorterDuff.Mode.SRC_ATOP);
initiated = true;
}
@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
Toast.makeText(Activity.this, "on Move", Toast.LENGTH_SHORT).show();
return false;
}
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int swipeDir) {
/*Toast.makeText(mcontext, "on Swiped ", Toast.LENGTH_SHORT).show();*/
Snackbar snackbar = Snackbar
.make(coordinatorLayout, "Deleted Successfully", Snackbar.LENGTH_LONG)
.setAction("UNDO", new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar snackbar1 = Snackbar.make(coordinatorLayout, "Message is restored!", Snackbar.LENGTH_SHORT);
snackbar1.show();
}
});
snackbar.show();
//Remove swiped item from list and notify the RecyclerView
int position = viewHolder.getAdapterPosition();
arrayList.remove(position);
adapter.notifyDataSetChanged();
}
@Override
public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
View itemView = viewHolder.itemView;
// not sure why, but this method get''s called for viewholder that are already swiped away
if (viewHolder.getAdapterPosition() == -1) {
// not interested in those
return;
}
if (!initiated) {
init();
}
// draw red background
background.setBounds(itemView.getRight() + (int) dX, itemView.getTop(), itemView.getRight(), itemView.getBottom());
background.draw(c);
int xMarkLeft = 0;
int xMarkRight = 0;
int xMarkTop = itemView.getTop() + (itemHeight - intrinsicHeight) / 2;
int xMarkBottom = xMarkTop + intrinsicHeight;
if (dX < 0) {
xMarkLeft = itemView.getRight() - xMarkMargin - intrinsicWidth;
xMarkRight = itemView.getRight() - xMarkMargin;
} else {
xMarkLeft = itemView.getLeft() + xMarkMargin;
xMarkRight = itemView.getLeft() + xMarkMargin + intrinsicWidth;
}
xMark.setBounds(xMarkLeft, xMarkTop, xMarkRight, xMarkBottom);
xMark.draw(c);
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
}
};
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(simpleItemTouchCallback);
itemTouchHelper.attachToRecyclerView(mRecyclerView);
Tuve que hacer esto el otro día y tuve algunos problemas, así que decidí escribir una publicación en el blog. No es necesario un tercero.
Básicamente, no dibujaría el "estado de deshacer" a través de onChildDraw
, se haría a través de ViewHolder
. Además, en realidad, no eliminaría la fila en onSwipe
solo onSwipe
como "pendiente de eliminar" y notificará al adaptador para que onSwipe
a onSwipe
en "estado de deshacer". Al mismo tiempo, Runnable
un Runnable
realmente elimina la fila en x segundos a menos que se presione el botón Deshacer ...
Código simple para RecyclerView Swipe:
ItemTouchHelper.SimpleCallback simpleItemTouchCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT | ItemTouchHelper.DOWN | ItemTouchHelper.UP) {
@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
Toast.makeText(ListActivity.this, "on Move", Toast.LENGTH_SHORT).show();
return false;
}
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int swipeDir) {
Toast.makeText(ListActivity.this, "on Swiped ", Toast.LENGTH_SHORT).show();
//Remove swiped item from list and notify the RecyclerView
int position = viewHolder.getAdapterPosition();
arrayList.remove(position);
adapter.notifyDataSetChanged();
}
};
A continuación, establezca la devolución de llamada para recyclerView con las siguientes declaraciones:
ItemTouchHelper itemTouchHelper = new ItemTouchHelper(simpleItemTouchCallback);
itemTouchHelper.attachToRecyclerView(rv);