ปัดเพื่อปิดสำหรับ RecyclerView [ปิด]


116

ฉันเคยใช้ไลบรารีSwipeToDismissแต่ตอนนี้ฉันกำลังพยายามย้ายไปที่ RecyclerView และสิ่งต่าง ๆ ก็ไม่ชัดเจนคุณรู้หรือไม่ว่ามีการแทนที่ lib นี้หรือไม่ มีความคิดอย่างไรในการใช้งานตั้งแต่เริ่มต้น?


1
ฉันได้สร้างห้องสมุดขนาดเล็กที่ใช้ ItemTouchHelper เพื่อสร้างท่าทางสัมผัสสำหรับการรีไซเคิลดูง่ายขึ้นคุณสามารถค้นหาได้ที่นี่ github.com/olmur/rvtools
Olexii Muraviov

คำตอบ:


337

ในเวอร์ชัน 22.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
จะเกิดอะไรขึ้นหากฉันต้องการจัดการกรณีที่ผู้ใช้ปัดบางส่วน แต่ลากมุมมองกลับมาในตำแหน่ง เห็นได้ชัดว่านี่ไม่สามารถแก้ไขได้ (?): โอเคเป็นไปได้ แต่มีระยะขอบเล็กน้อยที่คุณสามารถอยู่ได้ก่อนที่มุมมองจะถูกปัดเมื่อปล่อย ข้อเสนอแนะใด ๆ ?
Matteo

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

ที่นี่ใน Code หากผู้ใช้ปัดไปทางซ้าย AlertDialog จะปรากฏขึ้นและหากผู้ใช้เลือก REMOVE รายการจะถูกลบออกจากฐานข้อมูลและการรีไซเคิลรายการจะถูกรีเฟรชและหากผู้ใช้เลือก CANCEL การตรวจสอบการรีไซเคิลจะเป็นไปตามที่เป็นอยู่


ทำงานเก่ง.. ตอบดี.
Sagar Chavada

! น่ากลัว ใช้งานง่ายมาก
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 ด้วยปุ่ม "เลิกทำ" ซึ่งจะไม่ครอบคลุมใน lib ของคุณ
Viktor Yakunin

1
ไลบรารีจาก Daimajia ไม่รองรับคุณสมบัติการปัดเพื่อปิด
akohout

@raveN ฉันเพิ่งอัปเดตคำตอบของฉัน
Pierpaolo Paolini


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 ตรวจสอบให้แน่ใจว่าคุณเรียกใช้ super class constructor สิ่งนี้:

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 ของโครงการ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.