Remove item listview with Slide - Like Gmail

前端 未结 4 1425
北恋
北恋 2020-12-23 02:51

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

相关标签:
4条回答
  • 2020-12-23 03:00

    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.

    0 讨论(0)
  • 2020-12-23 03:10

    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.

    0 讨论(0)
  • 2020-12-23 03:15

    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.

    0 讨论(0)
  • 2020-12-23 03:17

    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.

    0 讨论(0)
提交回复
热议问题