SwipeListView открывает только один элемент за раз

Этот вопрос относится к компоненту SwipeListView, найденному здесь: https://github.com/47deg/android-swipelistview.

Попробовав несколько реализаций и исправлений, которые я нашел в Интернете, я решил немного изменить исходники.

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

SwipeListViewTouchListener.java претерпел следующие изменения:

...
/**
     * Create reveal animation
     *
     * @param view      affected view
     * @param swap      If will change state. If "false" returns to the original
     *                  position
     * @param swapRight If swap is true, this parameter tells if movement is toward
     *                  right or left
     * @param position  list position
     */
    private void generateRevealAnimate(final View view, final boolean swap, final boolean swapRight, final int position) {
        int moveTo = 0;
        if (opened.get(position)) {
            if (!swap) {
                moveTo = openedRight.get(position) ? (int) (viewWidth - rightOffset) : (int) (-viewWidth + leftOffset);
            }
        } else {
            if (swap) {
                moveTo = swapRight ? (int) (viewWidth - rightOffset) : (int) (-viewWidth + leftOffset);
            }
        }
        final boolean aux = !opened.get(position);
        if(swap) {
            opened.set(position, aux);
            openedRight.set(position, swapRight);
        }

        animate(view).translationX(moveTo).setDuration(animationTime).setListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                swipeListView.resetScrolling();

                if (swap) {
                    if (aux) {
                        swipeListView.onOpened(position, swapRight);
                    } else {
                        swipeListView.onClosed(position, openedRight.get(position));
                    }
                }
                // if (aux || !swap) {
                // resetCell();
                // }
            }
        });
    }
...

/**
     * Close all opened items
     */

    void closeOtherOpenedItems() {
        if (opened != null && downPosition != SwipeListView.INVALID_POSITION) {
            int start = swipeListView.getFirstVisiblePosition();
            int end = swipeListView.getLastVisiblePosition();
            for (int i = start; i <= end; i++) {
                if (opened.get(i) && i != downPosition) {
                    closeAnimate(swipeListView.getChildAt(i - start).findViewById(swipeFrontView), i);
                }
            }
        }

    }
...

/**
     * @see View.OnTouchListener#onTouch(android.view.View,
     * android.view.MotionEvent)
     */
    @Override
    public boolean onTouch(View view, MotionEvent motionEvent) {
...
closeOtherOpenedItems();
view.onTouchEvent(motionEvent);
return true;
}

Остальной не упомянутый код тот же.

Любые комментарии высоко ценятся, эти изменения избавляют вас от необходимости реализовывать SwipeListViewOnTouchListener в действии, которое раздувает список.


person Adrian Olar    schedule 24.03.2014    source источник
comment
Удивительно, спасибо! Он также решает другие проблемы, такие как эта: github.com/47deg/android-swipelistview/ вопросы/131   -  person ggurov    schedule 31.05.2014
comment
Работает хорошо без проблем.   -  person Madhur Ahuja    schedule 27.06.2014
comment
tnx решил мою проблему...   -  person Dhaval Parmar    schedule 06.08.2014
comment
какие изменения я должен сделать на OnTouch? куда добавить коды?   -  person Armin    schedule 07.10.2014
comment
Привет, Адриан, я бы очень хотел, чтобы этот код стал частью проекта 47deg. Если у вас нет времени, не возражаете, если я отправлю PR с этим (я укажу вам, как вы хотите)   -  person Kibi    schedule 07.12.2014
comment
Если я правильно помню, я действительно думаю, что сделал это, однако я не уверен в этом. Если хочешь, можешь проверить.   -  person Adrian Olar    schedule 07.12.2014


Ответы (4)


Минусы: не закрывает строку, открытую openAnimate()

   BaseSwipeListViewListener swipeListViewListener = new BaseSwipeListViewListener() {
    int openItem = -1;

    @Override
    public void onStartOpen(int position, int action, boolean right) {
        super.onStartOpen(position, action, right);

        if (openItem > -1)
            swipeListView.closeAnimate(openItem);

        openItem = position;
    }
   }

Или лучше:

 @Override
    public void onStartOpen(int position, int action, boolean right) {
        super.onStartOpen(position, action, right);
        swipeListView.closeOpenedItems();
    }

И установите прослушиватель в listView:

   swipeListView.setSwipeListViewListener(swipeListViewListener);
person lordmegamax    schedule 13.01.2015

Ваше исправление сработало, но есть способ сделать это, не затрагивая исходный код:

swipeListView.setSwipeListViewListener(new BaseSwipeListViewListener() {
    int openItem = -1;
    int lastOpenedItem = -1;
    int lastClosedItem = -1;

    @Override
    public void onOpened(int position, boolean toRight) {
        lastOpenedItem = position;
        if (openItem > -1 && lastOpenedItem != lastClosedItem) {
            swipeListView.closeAnimate(openItem);
        }
        openItem = position;
    }

    @Override
    public void onStartClose(int position, boolean right) {
        Log.d("swipe", String.format("onStartClose %d", position));
        lastClosedItem = position;
    }
}

Однако вам следует отправить запрос на извлечение, чтобы применить ваш код, так как это исправит ошибку.

Источник: https://github.com/47deg/android-swipelistview/issues/46

person spacebiker    schedule 03.09.2014
comment
Спасибо за ваши предложения, так как это не недавний пост, я сейчас не помню, но вполне возможно, что я также пробовал ваше исправление, сначала работало, но затем потерпело неудачу, пока что то, что я опубликовал, не показалось показать ошибки. - person Adrian Olar; 03.09.2014
comment
@spacebiker: Привет, можно ли закрыть определенный элемент, который уже открыт в списке? Я использовал closeAnimate (postion), но он не работает. - person Aerrow; 14.11.2014

Если вы собираетесь изменить саму библиотеку swipelistview, у меня есть более простое решение.

Добавьте следующий блок if в SwipeListViewTouchListener.java метода onTouch в самом начале case MotionEvent.ACTION_DOWN:

if(lastOpenedPosition != downPosition && opened.get(lastOpenedPosition)) {
    closeAnimate(lastOpenedPosition);
    return false;
}

Создайте поле int lastOpenedPosition и инициализируйте его значением 0, а в методе generateRevealAnimate внутри блока if (aux) добавьте:

lastOpenedPosition = position;

Я бы также добавил переменную конфигурации (в res/values/swipelistview_attrs.xml) в SwipeListView и добавил ее в блок onTouch if, чтобы добавить возможность включать и выключать эту функцию. В основном это приводит к тому, что если коснуться списка, когда строка открыта, строка закроется. Что, имхо, лучше по функциональности, чем закрытие строки только после того, как вы закончили открывать другую строку.

person Leo K    schedule 22.10.2014
comment
Привет, спасибо за ваш ответ, я действительно сталкивался с вашим решением ранее, оно работает, но не всегда. Мне нужно было что-то, что работало бы с более высокой точностью. Тот, который я дал здесь, является тем, который лучше всего работает для меня. - person Adrian Olar; 23.10.2014
comment
Интересно, а вы помните, в каких ситуациях это не работает? - person Leo K; 23.10.2014
comment
Это не что-то недавнее, так как вы можете видеть, что пост очень старый. Проблемы, с которыми я столкнулся, были случайными сбоями и ошибками с анимацией для списка. - person Adrian Olar; 23.10.2014

Да, SwipeListView оригинальных кодов может открывать много элементов одновременно. Ваш сегмент кода здесь может открыть один элемент за раз? Или при открытии другого элемента, открытые элементы будут закрыты?

person Community    schedule 21.04.2014
comment
После того, как один элемент открыт, а вы пытаетесь открыть другой, предыдущий элемент закроется, когда вы откроете другой. - person Adrian Olar; 21.04.2014