Android - Проведите по экрану, чтобы удалить RecyclerView

Я пытаюсь реализовать салфетки, чтобы удалить то же, что и приложение Gmail "Проведите в архив":

gmail swipe delete gmail swipe delete

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

Редактировать:

Мой код так far-

  ItemTouchHelper.SimpleCallback simpleItemTouchCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT) {
                public boolean onMove(RecyclerView recyclerView,
                                               RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
//                    final int fromPos = viewHolder.getAdapterPosition();
//                    final int toPos = viewHolder.getAdapterPosition();
//                    // move item in 'fromPos' to 'toPos' in adapter.
                    return true;// true if moved, false otherwise
                }

            @Override
            public void onSwiped(RecyclerView.ViewHolder viewHolder, int swipeDir) {
                //Remove swiped item from list and notify the RecyclerView
                mAdapter.notifyItemRemoved(viewHolder.getLayoutPosition());
            }
        };
        ItemTouchHelper itemTouchHelper = new ItemTouchHelper(simpleItemTouchCallback);
        itemTouchHelper.attachToRecyclerView(mRecyclerView);

Мне удалось включить жестов, но я не знаю, как добавить фон и изображение под viewHolder. Я попытался поместить другой файл FrameLayout в файл item_XXX.xml, но при прокрутке он бросает весь элемент с фоном.

Ответ 1

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

сообщение в блоге git repo

В принципе, вы не нарисовали бы "состояние отмены" через onChildDraw, это было бы сделано через ViewHolder. Также вы фактически не удаляете строку в onSwipe просто отмечаете ее как "ожидающее удаление" и уведомляете адаптер, чтобы переустановить его в "состоянии отмены". В то же время вы отправляете Runnable фактически удаляя строку за x секунд, если не нажата кнопка отмены...

Ответ 2

Простой код для прокрутки RecyclerView:

     ItemTouchHelper.SimpleCallback simpleItemTouchCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT | ItemTouchHelper.DOWN | ItemTouchHelper.UP) {

            @Override
            public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
                Toast.makeText(ListActivity.this, "on Move", Toast.LENGTH_SHORT).show();
                return false;
            }

            @Override
            public void onSwiped(RecyclerView.ViewHolder viewHolder, int swipeDir) {
                Toast.makeText(ListActivity.this, "on Swiped ", Toast.LENGTH_SHORT).show();
                //Remove swiped item from list and notify the RecyclerView
                int position = viewHolder.getAdapterPosition();
                arrayList.remove(position);
                adapter.notifyDataSetChanged();

            }
     };

Затем установите обратный вызов для recyclerView с инструкциями ниже:

ItemTouchHelper itemTouchHelper = new ItemTouchHelper(simpleItemTouchCallback);
 itemTouchHelper.attachToRecyclerView(rv);

Ответ 3

Это определенно сработает. Если вы хотите закусочную, используйте координаторLayout в своем xml. Вы можете установить фон так же, как gmail. Если у вас есть какие-либо мысли, просто нажмите ссылку

https://drive.google.com/open?id=11ZOrjMMSjdskt8gG8RP52V5Al5yE50dD

  ItemTouchHelper.SimpleCallback simpleItemTouchCallback = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT)

      {

                Drawable background;
                Drawable xMark;
                int xMarkMargin;
                boolean initiated;

                private void init() {
                    background = new ColorDrawable(Color.RED);
                    xMark = ContextCompat.getDrawable(Activity.this, R.drawable.ic_delete_svg);
                    xMark.setColorFilter(Color.WHITE, PorterDuff.Mode.SRC_ATOP);
                    initiated = true;
                }

                @Override
                public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
                    Toast.makeText(Activity.this, "on Move", Toast.LENGTH_SHORT).show();
                    return false;
                }

                @Override
                public void onSwiped(RecyclerView.ViewHolder viewHolder, int swipeDir) {
                    /*Toast.makeText(mcontext, "on Swiped ", Toast.LENGTH_SHORT).show();*/

                    Snackbar snackbar = Snackbar
                            .make(coordinatorLayout, "Deleted Successfully", Snackbar.LENGTH_LONG)
                            .setAction("UNDO", new View.OnClickListener() {
                                @Override
                                public void onClick(View view) {
                                    Snackbar snackbar1 = Snackbar.make(coordinatorLayout, "Message is restored!", Snackbar.LENGTH_SHORT);
                                    snackbar1.show();
                                }
                            });

                    snackbar.show();

                    //Remove swiped item from list and notify the RecyclerView
                    int position = viewHolder.getAdapterPosition();
                    arrayList.remove(position);
                    adapter.notifyDataSetChanged();

                }

                @Override
                public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
                    View itemView = viewHolder.itemView;

                    // not sure why, but this method get called for viewholder that are already swiped away
                    if (viewHolder.getAdapterPosition() == -1) {
                        // not interested in those
                        return;
                    }

                    if (!initiated) {
                        init();
                    }

                    // draw red background
                    background.setBounds(itemView.getRight() + (int) dX, itemView.getTop(), itemView.getRight(), itemView.getBottom());
                    background.draw(c);

                    int xMarkLeft = 0;
                    int xMarkRight = 0;
                    int xMarkTop = itemView.getTop() + (itemHeight - intrinsicHeight) / 2;
                    int xMarkBottom = xMarkTop + intrinsicHeight;
                    if (dX < 0) {
                        xMarkLeft = itemView.getRight() - xMarkMargin - intrinsicWidth;
                        xMarkRight = itemView.getRight() - xMarkMargin;
                    } else {
                        xMarkLeft = itemView.getLeft() + xMarkMargin;
                        xMarkRight = itemView.getLeft() + xMarkMargin + intrinsicWidth;
                    }
                    xMark.setBounds(xMarkLeft, xMarkTop, xMarkRight, xMarkBottom);
                    xMark.draw(c);

                    super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
                }

            };


            ItemTouchHelper itemTouchHelper = new ItemTouchHelper(simpleItemTouchCallback);
            itemTouchHelper.attachToRecyclerView(mRecyclerView);