Vuốt để loại bỏ cho RecyclerView [đã đóng]


116

Tôi đã từng sử dụng thư viện SwipeToDismiss nhưng bây giờ tôi đang cố gắng di chuyển sang RecyclerView và mọi thứ không quá rõ ràng, bạn có biết bất kỳ thay thế nào cho lib này không? Bất kỳ ý tưởng làm thế nào để thực hiện nó từ đầu?


1
Tôi đã thực hiện thư viện nhỏ mà sử dụng ItemTouchHelper để làm cho cử chỉ tạo cho recyclerview dễ dàng hơn, bạn có thể tìm thấy nó ở đây github.com/olmur/rvtools
Olexii Muraviov

Câu trả lời:


337

Kể từ phiên bản v22.2.0, nhóm hỗ trợ Android đã bao gồm một ItemTouchHelperlớp giúp thao tác vuốt để loại bỏ và kéo và thả khá đơn giản. Điều này có thể không có đầy đủ tính năng như một số thư viện hiện có, nhưng nó đến trực tiếp từ nhóm Android.

  • Cập nhật build.gradle của bạn để nhập v22.2. + Của thư viện RecyclerView

    compile 'com.android.support:recyclerview-v7:22.2.+'
  • Tạo một ItemTouchHelper với một SimpleCallback thích hợp

    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);

    ** Lưu ý rằng SimpleCallback thực hiện theo các hướng mà bạn muốn bật kéo và thả và các chỉ dẫn mà bạn muốn bật vuốt.

  • Đính kèm vào RecyclerView của bạn

    itemTouchHelper.attachToRecyclerView(recyclerView);

7
Làm cách nào để có được chỉ mục của mục đã vuốt?
MaTTo

37
@Orochi Bằng cách gọi getAdapterPosition () trên viewHolder.
SqueezyMo

1
Rõ ràng là họ đã không đặt quá nhiều suy nghĩ vào thiết kế của thành phần này. Nó chỉ hoạt động với RecyclerView. Vuốt để loại bỏ tồn tại cho những thứ như quán bar bán đồ ăn nhanh. Một thành phần chung chung hơn có thể được sử dụng với bất kỳ chế độ xem nào sẽ được hoan nghênh hơn.
AndroidDev

4
Điều gì sẽ xảy ra nếu tôi muốn xử lý trường hợp khi người dùng vuốt một phần nhưng sau đó kéo chế độ xem trở lại vị trí? Rõ ràng đây không phải là khả năng di động (?) CHỈNH SỬA: ok, nó là có thể di động, nhưng có một khoản tiền rất nhỏ mà bạn có thể ở lại trước khi chế độ xem được vuốt khi phát hành. Bất kì lời đề nghị nào?
Matteo

2
@Matteo: Thực hiện ItemTouchHelper.Callback và ghi đè 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

Ở đây trong Mã nếu người dùng vuốt sang trái thì AlertDialog sẽ được hiển thị và nếu người dùng chọn XÓA thì mục đó sẽ bị xóa khỏi cơ sở dữ liệu và chế độ xem tái chế được làm mới và nếu người dùng chọn HỦY thì chế độ xem lại sẽ như cũ.


làm việc tốt .. câu trả lời tốt đẹp.
Sagar Chavada

Tuyệt vời! Vì vậy, dễ thực hiện
dianakarenms

1
Bạn không thực sự cần kiểm tra hướng if (direction == ItemTouchHelper.LEFT) // if swipe leftItemTouchHelper.SimpleCallbackchỉ giới hạn ở hướng vuốt đó. Nếu bạn muốn vuốt sang trái và phải ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT)thì bạn cần kiểm tra hướng.
Jacko

1
Tôi thấy rằng việc nhấp vào bên ngoài AlertDialog đã hủy hộp thoại nhưng không đưa mục tôi đã vuốt trở lại. Bạn có thể nắm bắt điều này bằng cách thêm OnCancelListener vào 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 Hoạt động tốt. Tôi thấy adapter.notifyItemChanged(position);đã mang món đồ đã vuốt trở lại, thay vì notifyItemRemoved- điều đó hợp lý hơn.
winwaed vào

14

có thể bạn có thể thử thư viện này:

https://github.com/daimajia/AndroidSwipeLayout

Cập nhật: Tôi vừa tìm thấy một thư viện tốt khác mà bạn có thể sử dụng với RecyclerView:

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


Tôi đã thực hiện triển khai của riêng mình tương tự như github.com/krossovochkin/Android-SwipeToDismiss-RecyclerView . Yêu cầu duy nhất là hiển thị Bánh mì nướng với nút "Hoàn tác", điều này không có trong lib của bạn.
Viktor Yakunin

1
Thư viện từ Daimajia không hỗ trợ tính năng vuốt để loại bỏ.
akohout

@raveN Tôi vừa cập nhật câu trả lời của mình.
Pierpaolo Paolini


2

Tôi đã viết SwipeToDeleteRV thư viện hỗ trợ tính năng vuốt để xóa-hoàn tác trên các chế độ xem của trình tái chế. Nó dựa trên ItemTouchHelper và rất dễ sử dụng.

Hy vọng nó có thể hữu ích cho ai đó đang đối mặt với những vấn đề tương tự.

Ví dụ: bạn có thể xác định chế độ xem trình tái chế của mình trong một bố cục XML như bình thường, cộng với một số thuộc tính tùy chọn:

...
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"/>

Tất cả các thuộc tính stdrv là tùy chọn. Nếu bạn không chỉ định chúng, những cái mặc định sẽ được sử dụng.

Sau đó, tạo một bộ điều hợp phân lớp con STDAdapter, đảm bảo rằng bạn gọi hàm tạo siêu lớp. Một cái gì đó như thế này:

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

}

Tiếp theo, hãy đảm bảo rằng bạn thực hiện cuộc gọi đến setupSwipeToDeletephương thức để thiết lập tính năng vuốt để xóa.

mRecyclerView.setupSwipeToDelete(your_adapter_instance, swipe_directions);

swipe_directions là hướng bạn cho phép các mục được vuốt.

Thí dụ:

// 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);

Đó là nó! Để biết thêm các cài đặt nâng cao (tức là đặt các thông báo xóa khác nhau cho các mục khác nhau, xóa các mục tạm thời và vĩnh viễn, ...), vui lòng tham khảo trang readme của dự án.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.