android - recyclerview - Eliminar vista de lista de elementos con Diapositiva-Como Gmail
llenar un listview android (4)
Así es como me doy cuenta de este efecto. Tenemos un ListView lvSimple
y agregamos onTouchListener a nuestro lvSimple
. Este es mi código de trabajo.
float historicX = Float.NaN, historicY = Float.NaN;
static final int DELTA = 50;
enum Direction {LEFT, RIGHT;}
...
ListView lvSimple = (ListView) findViewById(R.id.linLayout);
...
lvSimple.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
historicX = event.getX();
historicY = event.getY();
break;
case MotionEvent.ACTION_UP:
if (event.getX() - historicX < -DELTA) {
FunctionDeleteRowWhenSlidingLeft();
return true;
}
else if (event.getX() - historicX > DELTA) {
FunctionDeleteRowWhenSlidingRight();
return true;
}
break;
default:
return false;
}
return false;
}
});
donde la función FunctionDeleteRowWhenSlidingLeft()
llama cuando cuando deslizamos hacia la izquierda, FunctionDeleteRowWhenSlidingRight()
- a la derecha respectivamente. En esta función necesitas pegar el código para la animación.
Estoy desarrollando una aplicación con una lista de compras en una vista de lista. Lo necesito cuando deslizo el elemento de la vista de lista hacia la derecha (o hacia la izquierda), este elemento debería eliminarse de la vista de lista.
Tengo mi vista de lista y solo necesito la función para hacerlo.
Gracias por adelantado.
Hice una respuesta usando lo que escribió el ciclo de vida. Por ahora está funcionando, pero solo funciona si todos sus hijos tienen la misma altura.
listView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
historicX = event.getX();
historicY = event.getY();
return false;
case MotionEvent.ACTION_UP:
if (listView.getChildAt(0) != null) {
int heightOfEachItem = haveListView.getChildAt(0).getHeight();
int heightOfFirstItem = -haveListView.getChildAt(0).getTop() + haveListView.getFirstVisiblePosition()*heightOfEachItem;
//IF YOU HAVE CHILDS IN LIST VIEW YOU START COUNTING
//listView.getChildAt(0).getTop() will see top of child showed in screen
//Dividing by height of view, you get how many views are not in the screen
//It needs to be Math.ceil in this case because it sometimes only shows part of last view
final int firstPosition = (int) Math.ceil(heightOfFirstItem / heightOfEachItem); // This is the same as child #0
//Here you get your List position, use historic Y to get where the user went first
final int wantedPosition = (int) Math.floor((historicY - haveListView.getChildAt(0).getTop()) / heightOfEachItem) + firstPosition;
//Here you get the actually position in the screen
final int wantedChild = wantedPosition - firstPosition;
//Depending on delta, go right or left
if (event.getX() - historicX < -DELTA) {
//If something went wrong, we stop it now
if (wantedChild < 0 || wantedChild >= List.size()|| wantedChild >= listView.getChildCount()) {
return true;
}
//Start animation with 500 miliseconds of time
listView.getChildAt(wantedChild).startAnimation(outToLeftAnimation(500));
//after 500 miliseconds remove from List the item and update the adapter.
new java.util.Timer().schedule(
new java.util.TimerTask() {
@Override
public void run() {
List.remove(wantedPosition);
updateAdapter();
}
},
500
);
return true;
} else if (event.getX() - historicX > DELTA) {
//If something went wrong, we stop it now
if (wantedChild < 0 || wantedChild >= List.size() || wantedChild >= listView.getChildCount()) {
return true;
}
//Start animation with 500 miliseconds of time
listView.getChildAt(wantedChild).startAnimation(outToRightAnimation(500));
//after 500 miliseconds remove from List the item and update the adapter.
new java.util.Timer().schedule(
new java.util.TimerTask() {
@Override
public void run() {
List.remove(wantedPosition);
updateAdapter();
}
},
500
);
return true;
}
}
return true;
default:
return false;
}
}
});
Las animaciones tienen esta función:
private Animation outToLeftAnimation(int duration) {
Animation outtoLeft = new TranslateAnimation(
Animation.RELATIVE_TO_PARENT, 0.0f,
Animation.RELATIVE_TO_PARENT, -1.0f,
Animation.RELATIVE_TO_PARENT, 0.0f,
Animation.RELATIVE_TO_PARENT, 0.0f);
outtoLeft.setDuration(duration);
outtoLeft.setInterpolator(new AccelerateInterpolator());
return outtoLeft;
}
private Animation outToRightAnimation(int duration) {
Animation outtoRight = new TranslateAnimation(
Animation.RELATIVE_TO_PARENT, 0.0f,
Animation.RELATIVE_TO_PARENT, +1.0f,
Animation.RELATIVE_TO_PARENT, 0.0f,
Animation.RELATIVE_TO_PARENT, 0.0f);
outtoRight.setDuration(duration);
outtoRight.setInterpolator(new AccelerateInterpolator());
return outtoRight;
}
Estoy intentando esto, y hasta ahora no he visto errores, si alguien pudiera intentarlo también sería bueno.
Otra opción que debe considerar es usar la biblioteca EnhancedListView Tim Roes. [Actualización - 01/08/2015] Con la presentación de RecycleView esta biblioteca ha quedado obsoleta.
El oyente SwipeToDismiss de Roman Nurik antes mencionado requiere API de nivel 12 o superior. Jake Wharton ha portado este código para admitir todos los niveles de API en SwipeToDismissNOA .
Tim Roes amplió aún más esta biblioteca para admitir la función Deshacer .
Answer de Android-Developer apunta al código de Roman Nurik en gist.github.com . Este código no está actualizado. Utiliza este oyente Swipe to Dismiss en su proyecto abierto Dash Clock .
Hay algunas cosas que debe saber antes de usar el código en Gist.github.com.
- El código obsoleto en gist.Github es muy sensible a los toques. Si continúa tocando un elemento en ListView, se eliminará. En el código actualizado él arregló la sensibilidad de fling.
- Este oyente no funciona bien si tiene divisores declarados en ListView. Si quieres divisores, declaralos en el diseño ListItem.
- Este código todavía está en beta . Caveat Emptor.
Entonces recomiendo usar el código actualizado. Puede encontrar la fuente actualizada here .