SwipeListView only one item opened at a time

android, ontouchlistener, swipe, swipe-gesture

Solution

Cons: doesn't close the row opened by `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;
    }
   }

Or better way:

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

And set the listener to the listView:

   swipeListView.setSwipeListViewListener(swipeListViewListener);

Problem

This question refers to the SwipeListView component found here: https://github.com/47deg/android-swipelistview After trying out several implementations and fixes I found on the web I decided to modify the sources a little. I will post this here since i know it's a known issue and all the versions I found proved to have some issues eventually. `SwipeListViewTouchListener.java` has suffered the following changes: ``` ... /** * 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; } ``` The rest of the code not mentioned is the same. Any comments highly appreciated, this changes prevent you from having to implement the `SwipeListViewOnTouchListener` in the activity which inflates the list.

Original source