Проведіть пальцем, щоб відхилити RecyclerView [закрито]


116

Раніше я працював у бібліотеці SwipeToDismiss, але зараз я намагаюся перейти на RecyclerView, і все не так очевидно, чи знаєте ви якісь заміни для цієї бібліотеки? Будь-які ідеї, як реалізувати це з нуля?


1
Я зробив маленьку бібліотеку , яку використовують ItemTouchHelper , щоб створити жести для recyclerview простіше, ви можете знайти його тут github.com/olmur/rvtools
Olexii Муравйов

Відповіді:


337

Станом на v22.2.0, команда підтримки Android включила ItemTouchHelperклас, який робить проведенне перекидання та перетягування досить простим. Це може бути не таким повнофункціональним, як деякі бібліотеки, але це безпосередньо від команди Android.

  • Оновіть build.gradle, щоб імпортувати v22.2. + Бібліотеки RecyclerView

    compile 'com.android.support:recyclerview-v7:22.2.+'
  • Імпульсуйте ItemTouchHelper за допомогою відповідного SimpleCallback

    ItemTouchHelper.SimpleCallback simpleItemTouchCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {
        [...]
        @Override
        public void onSwiped(RecyclerView.ViewHolder viewHolder, int swipeDir) {
            //Remove swiped item from list and notify the RecyclerView
        }
    };
    
    ItemTouchHelper itemTouchHelper = new ItemTouchHelper(simpleItemTouchCallback);

    ** Зауважте, що SimpleCallback приймає вказівки, до яких потрібно ввімкнути перетягування, та напрямки, які потрібно активувати.

  • Приєднайте до свого RecyclerView

    itemTouchHelper.attachToRecyclerView(recyclerView);

7
Як можна отримати індекс розміщеного елемента?
MaTTo

37
@Orochi Зателефонувавши на getAdapterPosition () на viewHolder.
SqueezyMo

1
Вони, очевидно, не надто замислювалися над розробкою цього компонента. Він працює лише з RecyclerView. Проведіть пальцем до відхилення такі речі, як закусочні. Більш загальний компонент, який можна було б використати при будь-якому погляді, був би привітаний.
AndroidDev

4
Що робити, якщо я хочу вирішити випадок, коли користувач частково провести пальцем, а потім перетягнути погляд назад у положення? Мабуть, це не можливо (?) EDIT: гаразд, це можливо, але є дуже маленький запас, на якому ви можете залишитися, перш ніж вигляд буде перенесений на реліз. Будь-яка пропозиція?
Маттео

2
@Matteo: впровадити ItemTouchHelper.Callback і перекрити getSwipeThreshold ()
Sofi Software LLC

36
 ItemTouchHelper.SimpleCallback simpleCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT) {
        @Override
        public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
            return false;
        }

        @Override
        public void onSwiped(final RecyclerView.ViewHolder viewHolder, int direction) {
            final int position = viewHolder.getAdapterPosition(); //get position which is swipe

            if (direction == ItemTouchHelper.LEFT) {    //if swipe left

                AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this); //alert for confirm to delete
                builder.setMessage("Are you sure to delete?");    //set message

                builder.setPositiveButton("REMOVE", new DialogInterface.OnClickListener() { //when click on DELETE
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        adapter.notifyItemRemoved(position);    //item removed from recylcerview
                        sqldatabase.execSQL("delete from " + TABLE_NAME + " where _id='" + (position + 1) + "'"); //query for delete
                        list.remove(position);  //then remove item

                        return;
                    }
                }).setNegativeButton("CANCEL", new DialogInterface.OnClickListener() {  //not removing items if cancel is done
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        adapter.notifyItemRemoved(position + 1);    //notifies the RecyclerView Adapter that data in adapter has been removed at a particular position.
                        adapter.notifyItemRangeChanged(position, adapter.getItemCount());   //notifies the RecyclerView Adapter that positions of element in adapter has been changed from position(removed element index to end of list), please update it.
                        return;
                    }
                }).show();  //show alert dialog
            }
        }
    };
    ItemTouchHelper itemTouchHelper = new ItemTouchHelper(simpleCallback);
    itemTouchHelper.attachToRecyclerView(recyclerView); //set swipe to recylcerview

Тут, у коді, якщо користувач проведіть пальцем ліворуч, відобразиться AlertDialog, а якщо користувач вибере REMOVE, то пункт буде видалено з бази даних, а перегляд рецилер буде оновлений, а якщо користувач вибере CANCEL, тоді reciklierview буде таким, яким він є.


добре працює .. приємна відповідь.
Сагар Чавада

Дивовижно! Настільки прості у здійсненні
dianakarenms

1
Ви дійсно не потребуєте перевірки напрямку, if (direction == ItemTouchHelper.LEFT) // if swipe leftоскільки ItemTouchHelper.SimpleCallbackобмеження обмежується лише цим напрямком пальця. Якщо ви хочете пальцями ліворуч і праворуч, ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT)тоді вам потрібно буде перевірити напрямок.
Jacko

1
Я виявив, що натискання за межами AlertDialog скасовує діалогове вікно, але не поставив елемент, який я провела назад. Ви можете зафіксувати це додавання OnCancelListener до BuilderAlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);builder.setOnCancelListener(new DialogInterface.OnCancelListener() { @Override public void onCancel(DialogInterface dialog) { // stuff to put the item back } });
Jacko

1
+1 добре працює. Я виявив, що adapter.notifyItemChanged(position);повернув перевезений предмет, а не notifyItemRemoved- що більш логічно.
winwaed

14

можливо, ви можете спробувати цю бібліотеку:

https://github.com/daimajia/AndroidSwipeLayout

Оновлення. Щойно я знайшов ще одну хорошу бібліотеку, яку можна використовувати з RecyclerView:

https://github.com/hudomju/android-swipe-to-dismiss-undo


Я зробив власну реалізацію подібною до github.com/krossovochkin/Android-SwipeToDismiss-RecyclerView . Єдина вимога полягала в тому, щоб показати Toast кнопкою "Скасувати", яка не закрита у вашій губі.
Віктор Якунін

1
Бібліотека від Daimajia не підтримує функцію швидкого перемикання.
akohout

@raveN Я щойно оновив свою відповідь.
П’єрпаоло Паоліні


2

Я написав бібліотеку SwipeToDeleteRV, яка підтримує функцію "проведіть пальцем для видалення-скасування" на переглядах рециркулятора. Він заснований на ItemTouchHelper і дуже простий у використанні.

Сподіваюся, це може бути корисним для тих, хто стикається з тими ж проблемами.

Як приклад, ви можете визначити перегляд рециркулятора в макеті XML як звичайний плюс додаткові атрибути:

...
xmlns:stdrv="http://schemas.android.com/apk/res-auto"
...
<io.huannguyen.swipetodeleterv.STDRecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
stdrv:border_color="@android:color/darker_gray" // specify things like border color, border width, etc.
stdrv:delete_view_background="#cccccc"
stdrv:delete_icon="@drawable/ic_archive"
stdrv:delete_icon_height="24dp"
stdrv:delete_icon_width="24dp"
stdrv:left_delete_icon_margin="32dp"
stdrv:delete_message="@string/delete_message"
stdrv:right_delete_icon_margin="32dp"
stdrv:delete_icon_color="#000000"
stdrv:has_border="true"/>

Усі атрибути stdrv необов'язкові. Якщо їх не вказати, будуть використані типові за замовчуванням.

Потім створіть адаптер, що підкласи STDAdapter, переконайтеся, що ви викликаєте конструктор суперкласу. Щось на зразок цього:

public class SampleAdapter extends STDAdapter<String> {
public SampleAdapter(List<String> versionList) {
    super(versionList);
}

}

Далі переконайтеся, що ви здійснили виклик setupSwipeToDeleteметоду, щоб налаштувати функцію проведення пальцем для видалення.

mRecyclerView.setupSwipeToDelete(your_adapter_instance, swipe_directions);

swipe_directions - це напрямок, у якому ви можете перемикати елементи.

Приклад:

// Get your recycler view from the XML layout
mRecyclerView = (STDRecyclerView) findViewById(R.id.recycler_view);
LayoutManager layoutManager = new LinearLayoutManager(getApplicationContext());
mRecyclerView.setLayoutManager(layoutManager);
mAdapter = new SampleAdapter(versions);
// allow swiping in both directions (left-to-right and right-to-left)
mRecyclerView.setupSwipeToDelete(mAdapter, ItemTouchHelper.LEFT|ItemTouchHelper.RIGHT);

Це воно! Для отримання більш розширених налаштувань (тобто встановлення різних повідомлень про видалення для різних елементів, тимчасово та назавжди видаліть елементи, ...), будь ласка, зверніться до сторінки проекту readme.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.