web-dev-qa-db-fra.com

Supprimer la liste des éléments avec Slide - Like Gmail

Je développe une application avec une liste de magasin dans une liste. J'ai besoin que lorsque je balaie l'élément de listview à droite (ou à gauche), cet élément soit supprimé de la liste.

J'ai ma listview et seulement besoin de la fonction pour le faire.

Merci d'avance.

40
dmontielfdez

C'est comme ça que je réalise cet effet. Nous avons un ListView lvSimple et nous ajoutons onTouchListener à notre lvSimple. Ceci est mon code de travail.

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;
    }
});

où la fonction FunctionDeleteRowWhenSlidingLeft() appelle quand nous glissons à gauche, FunctionDeleteRowWhenSlidingRight() - à droite, respectivement. Dans cette fonction, vous avez besoin d'un code de collage pour l'animation.

19
macloving

Answer by Android-Developer pointe vers le code de Roman Nurik dans Gist.github.com . Ce code est obsolète. Il utilise cet auditeur de glisser à rejeter dans son projet en source libre Dash Clock

Il y a certaines choses que vous devez savoir avant d'utiliser le code dans Gist.github.com. 

  1. Le code obsolète de Gist.Github est très sensible au toucher. Si vous continuez à appuyer sur un élément dans ListView, il sera supprimé. Dans le code mis à jour, il corrigeait la sensibilité au lancer.
  2. Cet écouteur ne fonctionne pas bien si des diviseurs sont déclarés dans ListView. Si vous voulez des séparateurs, déclarez-les dans la disposition ListItem.
  3. Ce code est toujours dans beta. Caveat emptor. 

Je recommande donc d'utiliser le code mis à jour. Vous pouvez trouver la source mise à jour ici .

6
iraSenthil

Une autre option que vous devriez envisager est d'utiliser EnhancedListView library de Tim Roes.[Mise à jour - 01/08/2015] Avec l'introduction de RecycleView cette bibliothèque est obsolète. 

L’auditeur SwipeToDismiss de Roman Nurik susmentionné nécessite un niveau 12 ou supérieur d’API. Jake Wharton a porté ce code pour prendre en charge tous les niveaux d'API dans SwipeToDismissNOA

Tim Roes a étendu cette bibliothèque pour prendre en charge la fonction Undo.

5
Alex Lipov

J'ai fait une réponse en utilisant ce que macloving a écrit. Pour l'instant cela fonctionne, mais ce n'est que si tous vos enfants ont la même hauteur.

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;
            }
        }
    });

Les animations ont cette fonction:

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;
}

J'essaie ceci, et jusqu'à présent je n'ai pas vu d'erreurs, si quelqu'un pouvait essayer aussi, ce serait bien.

0
Dinidiniz