Подтвердить что ты не робот

Удаление списка элементов списка с помощью слайд - как Gmail

Я разрабатываю приложение с списком магазинов в списке. Мне нужно, чтобы при прокрутке элемента listview вправо (или влево) этот элемент должен быть удален из списка.

У меня есть список и мне нужна только функция.

Спасибо заранее.

4b9b3361

Ответ 1

Вот как я понимаю этот эффект. У нас есть ListView lvSimple, и мы добавляем onTouchListener в наш lvSimple. Это мой рабочий код.

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

где функция FunctionDeleteRowWhenSlidingLeft() вызывается, когда мы сдвигаемся влево, FunctionDeleteRowWhenSlidingRight() - вправо соответственно. В этой функции вам нужен код вставки для анимации.

Ответ 2

Отвечать на Android-Developer указывает на код Roman Nurik в gist.github.com. Этот код устарел. Он использует этот Swipe to Dismass listener в своем открытом проекте Dash Clock.

Есть некоторые вещи, которые вы должны знать, прежде чем использовать код в Gist.github.com.

  • Устаревший код в gist.Github очень чувствителен к касаниям. Если вы продолжаете нажимать элемент в ListView, он будет удален. В обновленном коде он зафиксировал чувствительность перехода.
  • Этот прослушиватель не работает, если у вас есть разделители, объявленные в Посмотреть список. Если вы хотите делителей, объявите их в макете ListItem.
  • Этот код по-прежнему находится в beta​​strong > . Пусть покупатель будет бдителен.

Поэтому я рекомендую использовать обновленный код. Вы можете найти обновленный источник здесь.

Ответ 3

Еще один вариант, который вы должны рассмотреть, - использовать библиотеку Tim Roes EnhancedListView. [Обновить - 8/1/2015] С введением RecycleView эта библиотека устарела.

Вышеупомянутый слушатель Roman Nurik SwipeToDismiss требует уровня API 12 или выше. Джейк Уортон портировал этот код для поддержки всех уровней API в SwipeToDismissNOA.

Тим Рос также расширил эту библиотеку для поддержки функции Отменить.

Ответ 4

Я сделал ответ, используя то, что написал macloving. На данный момент он работает, но он работает только в том случае, если все ваши дети имеют одинаковую высоту.

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

У анимаций есть эта функция:

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

Я пытаюсь это сделать, и до сих пор я не видел ошибок, если бы кто-то мог попробовать, это было бы хорошо.