Remove item listview with Slide - Like Gmail
Asked Answered
L

4

41

I am developing an application with a shop list in a listview. I need that when I swipe the item of listview to the right(or left), this item should get deleted from the listview.

I have my listview and only need the function to do it.

Thanks in advance.

Loft answered 18/1, 2013 at 12:14 Comment(2)
just like tablets, where you remove the task from current tasks list by swiping them to either left or right.?Offside
Here is a link which can show / guide you how to do that : Swipe to dismiss .Cadal
C
19

This is how I realize this effect. We have a ListView lvSimple and we add onTouchListener to our lvSimple. This is my working code.

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

where function FunctionDeleteRowWhenSlidingLeft() is calling when when we sliding to the left, FunctionDeleteRowWhenSlidingRight() - to the right respectively. In this function you need paste code for animation.

Coquelicot answered 10/4, 2013 at 0:20 Comment(5)
Ohhhh, after searching and debugging for two days , it saves me ! ThanksBrail
but how to get the index of the slide row ?!Brail
list.setOnItemClickListener(new AdapterView.OnItemClickListener() { public void onItemClick(AdapterView parent, View v, int position, long id){ // DO STUFF HERE SwipedPosition = position; } });Nailbiting
The Swipe position remains 0 and the first item in the list is deleted. How to get the position of the swipe item of the list view?Brookes
@macloving, could you please extend your answer with the animation code as well?Ragnar
G
6

Answer by Android-Developer points to Roman Nurik's code in gist.github.com. This code is out of date. He uses this Swipe to Dismiss listener in his open sourced project Dash Clock.

There are some things you should know, before you use the code in Gist.github.com.

  1. The outdated code in gist.Github is very sensitive to touches. If you keep on tapping an item in the ListView, it will be deleted. In the updated code he fixed the fling sensitivity.
  2. This listener doesn't work well if you have dividers declared in ListView. If you want dividers, declare them in the ListItem layout.
  3. This code is still in beta. Caveat emptor.

So I recommend using the updated code. You can find the updated source here.

Goodin answered 24/7, 2013 at 14:55 Comment(3)
I am using the updated code found at the link you recommended, but I am having an issue in declaring it. Whenever I call the line: "new SwipeDismissListViewTouchListener.OnDismissCallback() {" It comes up with, "SwipeDismissListViewTouchListener.OnDismissCallback cannot be resolved to a type" Any ideas? Not really sure of the solutionChlorous
@Silmarilos Use new SwipeDismissListViewTouchListener.DismissCallbacks() insteadAccompany
github.com/romannurik/Android-SwipeToDismiss/blob/master/src/…Sewerage
A
5

Another option you should consider is to use Tim Roes's EnhancedListView library. [Update - 8/1/2015] With the introduction of RecycleView this library has been deprecated.

The aforementioned Roman Nurik's SwipeToDismiss listener requires API level 12 or higher. Jake Wharton ported this code to support all API levels in SwipeToDismissNOA.

Tim Roes extended this library further to support Undo feature as well.

Agustinaah answered 2/8, 2014 at 17:19 Comment(2)
INFO: EnhancedListView is deprecated.Goodin
@Goodin So what have you been using now or swipe and delete? SwipetoDismissNOA or something else?Follicle
U
0

I made an answer using what macloving wrote. For now it is working, but it is only work if all your childs have the same height.

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

The animations have this function:

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

I am trying this, and until now i haven't seen errors, if someone could try as well would be good.

Uglify answered 10/5, 2016 at 2:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.