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
в активности, которая раздувает список.
Ответы
Ответ 1
Минусы: не закрывает строку, открытую 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);
Ответ 2
Ваше исправление работает, но есть способ сделать это, не затрагивая исходный код:
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
Ответ 3
Если вы собираетесь изменить библиотеку 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, чтобы добавить возможность отключить и включить эту функцию.
Это в основном приводит к тому, что список затрагивается, когда строка открыта, чем строка закрывается. Который, imho, имеет лучшую функциональность, чем закрытие строки только после того, как вы закончили открытие другой строки.
Ответ 4
swipeListView.setSwipeListViewListener(new BaseSwipeListViewListener() {
//...
@Override
public void onClickBackView(int position) {
//DELETE ITEM
adapter.notifyDataSetChanged();
swipeListView.closeOpenedItems();
}
//...
});
Ответ 5
Да, SwipeListView исходных кодов может одновременно открывать множество элементов. Ваш сегмент кода здесь может открыть один элемент за один раз? Или, если открыт другой элемент, открытые элементы будут закрыты?