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

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

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

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

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 в активности, которая раздувает список.

Solutions Collecting From Web of "SwipeListView одновременно открывается только один элемент"

Минусы: не закрывает строку, открытую 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); 

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

 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

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

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

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

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

 lastOpenedPosition = position; 

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

 swipeListView.setSwipeListViewListener(new BaseSwipeListViewListener() { //... @Override public void onClickBackView(int position) { //DELETE ITEM adapter.notifyDataSetChanged(); swipeListView.closeOpenedItems(); } //... }); 

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