Est-ce que quelqu'un a un exemple simple d'une activité de liste affichant des vues de texte dans une colonne et lorsque vous glissez de gauche à droite, vous voyez cette ligne dans une nouvelle vue ? Il s'agirait de modifier les données de cette ligne ou de montrer des informations plus détaillées sur cette ligne. Veuillez ne pas faire référence à Code Shogun ou à d'autres sites, car j'ai fait des recherches sur Google et je n'ai pas trouvé de réponse à cette question.
Réponses
Trop de publicités?J'ai eu le même problème et je n'ai pas trouvé ma réponse ici.
Je voulais détecter une action de balayage dans un élément ListView et le marquer comme balayé, tout en continuant à supporter OnItemClick et OnItemLongClick.
Voici ma solution :
1. La classe SwipeDetector :
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
public class SwipeDetector implements View.OnTouchListener {
public static enum Action {
LR, // Left to Right
RL, // Right to Left
TB, // Top to bottom
BT, // Bottom to Top
None // when no action was detected
}
private static final String logTag = "SwipeDetector";
private static final int MIN_DISTANCE = 100;
private float downX, downY, upX, upY;
private Action mSwipeDetected = Action.None;
public boolean swipeDetected() {
return mSwipeDetected != Action.None;
}
public Action getAction() {
return mSwipeDetected;
}
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
downX = event.getX();
downY = event.getY();
mSwipeDetected = Action.None;
return false; // allow other events like Click to be processed
case MotionEvent.ACTION_UP:
upX = event.getX();
upY = event.getY();
float deltaX = downX - upX;
float deltaY = downY - upY;
// horizontal swipe detection
if (Math.abs(deltaX) > MIN_DISTANCE) {
// left or right
if (deltaX < 0) {
Log.i(logTag, "Swipe Left to Right");
mSwipeDetected = Action.LR;
return false;
}
if (deltaX > 0) {
Log.i(logTag, "Swipe Right to Left");
mSwipeDetected = Action.RL;
return false;
}
} else if (Math.abs(deltaY) > MIN_DISTANCE) { // vertical swipe
// detection
// top or down
if (deltaY < 0) {
Log.i(logTag, "Swipe Top to Bottom");
mSwipeDetected = Action.TB;
return false;
}
if (deltaY > 0) {
Log.i(logTag, "Swipe Bottom to Top");
mSwipeDetected = Action.BT;
return false;
}
}
return false;
}
return false;
}
}
2. J'utilise la classe de détecteur de glissement dans la vue en liste :
final ListView lv = getListView();
final SwipeDetector swipeDetector = new SwipeDetector();
lv.setOnTouchListener(swipeDetector);
lv.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if (swipeDetector.swipeDetected()){
// do the onSwipe action
} else {
// do the onItemClick action
}
}
});
lv.setOnItemLongClickListener(new OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view,int position, long id) {
if (swipeDetector.swipeDetected()){
// do the onSwipe action
} else {
// do the onItemLongClick action
}
}
});
De cette façon, je peux prendre en charge trois actions - glisser, cliquer, cliquer longuement et je peux utiliser les informations sur les éléments de la liste.
AJOUTÉ PLUS TARD :
Comme le ListView capte une action de défilement, il est parfois difficile de le faire glisser. Pour résoudre ce problème, j'ai apporté la modification suivante à SwipeDetector.onTouch :
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: {
downX = event.getX();
downY = event.getY();
mSwipeDetected = Action.None;
return false; // allow other events like Click to be processed
}
case MotionEvent.ACTION_MOVE: {
upX = event.getX();
upY = event.getY();
float deltaX = downX - upX;
float deltaY = downY - upY;
// horizontal swipe detection
if (Math.abs(deltaX) > HORIZONTAL_MIN_DISTANCE) {
// left or right
if (deltaX < 0) {
Log.i(logTag, "Swipe Left to Right");
mSwipeDetected = Action.LR;
return true;
}
if (deltaX > 0) {
Log.i(logTag, "Swipe Right to Left");
mSwipeDetected = Action.RL;
return true;
}
} else
// vertical swipe detection
if (Math.abs(deltaY) > VERTICAL_MIN_DISTANCE) {
// top or down
if (deltaY < 0) {
Log.i(logTag, "Swipe Top to Bottom");
mSwipeDetected = Action.TB;
return false;
}
if (deltaY > 0) {
Log.i(logTag, "Swipe Bottom to Top");
mSwipeDetected = Action.BT;
return false;
}
}
return true;
}
}
return false;
}
Voici un extrait que j'utilise pour détecter les balayages. Vous pourriez alors utiliser un nageoire de vue pour changer la vue.
@Override
public boolean onTouchEvent(MotionEvent event) {
if (gestureDetector.onTouchEvent(event)) {
return true;
} else {
return false;
}
}
private static final int SWIPE_MIN_DISTANCE = 30;
private static final int SWIPE_MAX_OFF_PATH = 250;
private static final int SWIPE_THRESHOLD_VELOCITY = 200;
class MyGestureDetector extends SimpleOnGestureListener {
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
try {
if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH)
return false;
// right to left swipe
if (e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE
&& Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
leftFling();
} else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE
&& Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
rightFling();
}
} catch (Exception e) {
// nothing
}
return false;
}
}
Voici une version très simplifiée utilisant les deux écouteurs (onTouch pour la détection du glissement, et onClickIem pour la détection du clic sur l'élément). utilisation de l'indicateur isSwipe pour arrêter l'écouteur onClickItemListener jusqu'à ce qu'il soit confirmé qu'il ne s'agit pas d'un balayage.
Détection du clic
en tenant compte du fait qu'il ne s'agit pas d'un premier coup de balai
listView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3)
{
if(!isSwipe)
{
adapter.increase(arg2);
adapter.notifyDataSetChanged();
}
}
});
Détection de l'essuyage
listView.setOnTouchListener(new OnTouchListener() {
private int action_down_x = 0;
private int action_up_x = 0;
private int difference = 0;
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
action_down_x = (int) event.getX();
isSwipe=false; //until now
break;
case MotionEvent.ACTION_MOVE:
if(!isSwipe)
{
action_up_x = (int) event.getX();
difference = action_down_x - action_up_x;
if(Math.abs(difference)>50)
{
Log.d("action","action down x: "+action_down_x);
Log.d("action","action up x: "+action_up_x);
Log.d("action","difference: "+difference);
//swipe left or right
if(difference>0){
//swipe left
Log.d("action","swipe left");
adapter.decrease(selectedItem);
adapter.notifyDataSetChanged();
}
else{
//swipe right
Log.d("action","swipe right");
}
isSwipe=true;
}
}
break;
case MotionEvent.ACTION_UP:
Log.d("action", "ACTION_UP - ");
action_down_x = 0;
action_up_x = 0;
difference = 0;
break;
}
return false; //to allow the clicklistener to work after
}
})
Si vous voulez afficher des boutons avec des actions lorsqu'un élément de liste est glissé, il existe de nombreuses bibliothèques sur Internet qui ont ce comportement. J'ai implémenté la bibliothèque que j'ai trouvée sur internet et je suis très satisfait. C'est très simple à utiliser et très rapide. J'ai amélioré la bibliothèque originale et j'ai ajouté un nouvel écouteur de clic pour le clic sur l'élément. J'ai également ajouté une bibliothèque de polices de caractères ( http://fortawesome.github.io/Font-Awesome/ ) et maintenant vous pouvez simplement ajouter un nouveau titre d'élément et spécifier le nom de l'icône à partir de la police awesome.
Ici est le lien github