スワイプしてRecyclerViewを閉じます[終了]


116

以前はSwipeToDismissライブラリを使用していましたが、今はRecyclerViewに移行しようとしていますが、それほど明確ではありません。このlibの代替品を知っていますか?ゼロから実装する方法はありますか?


1
私はItemTouchHelperを使用してrecyclerviewのジェスチャー作成を簡単にする小さなライブラリを作成しました。ここで見つけることができますgithub.com/olmur/rvtools
Olexii Muraviov

回答:


337

v22.2.0の時点で、Androidサポートチームには、ItemTouchHelperスワイプによる非表示とドラッグアンドドロップを非常に簡単にするクラスが含まれています。一部のライブラリほどフル機能ではないかもしれませんが、Androidチームから直接提供されています。

  • build.gradleを更新して、RecyclerViewライブラリのv22.2。+をインポートします。

    compile 'com.android.support:recyclerview-v7:22.2.+'
  • 適切なSimpleCallbackを使用してItemTouchHelperをインスタンス化します。

    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 2015

37
@OrochiでgetAdapterPosition()を呼び出しviewHolderます。
SqueezyMo 2015

1
彼らは明らかに、このコンポーネントの設計をあまり考慮していません。RecyclerViewでのみ機能します。スワイプして却下は、スナックバーなどに存在します。任意のビューで使用できるより一般的なコンポーネントがより歓迎されます。
AndroidDev 2015年

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

このコードでは、ユーザーが左にスワイプするとAlertDialogが表示され、ユーザーがREMOVEを選択するとアイテムがデータベースから削除されてrecyclerviewが更新され、ユーザーがCANCELを選択するとrecyclerviewがそのまま表示されます。


良い仕事をしています。
Sagar Chavada 2017

驚くばかり!実装が非常に簡単
dianakarenms 2017年

1
スワイプの方向のみに限定さif (direction == ItemTouchHelper.LEFT) // if swipe leftれてItemTouchHelper.SimpleCallbackいるため、方向チェックは実際には必要ありません。左右にスワイプしたい場合はItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT)、方向を確認する必要があります。
Jacko

1
AlertDialogの外側をクリックするとダイアログがキャンセルされたが、スワイプして元に戻せなかったことがわかりました。あなたは、これはビルダーにOnCancelListener追加取り込むことができますAlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);builder.setOnCancelListener(new DialogInterface.OnCancelListener() { @Override public void onCancel(DialogInterface dialog) { // stuff to put the item back } });
ジャッコ

1
+1うまくいきます。私adapter.notifyItemChanged(position);はスワイプされたアイテムを持ち帰ったのではなく、notifyItemRemovedより論理的な私見であることがわかりました。
2018

14

多分あなたはこのライブラリを試すことができます:

https://github.com/daimajia/AndroidSwipeLayout

更新:RecyclerViewで使用できる別の良いライブラリを見つけました:

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


github.com/krossovochkin/Android-SwipeToDismiss-RecyclerViewに似た独自の実装を作成しました。唯一の要件は、「元に戻す」ボタンでToastを表示することでしたが、これはライブラリには含まれていません。
Viktor Yakunin 2015

1
Daimajiaのライブラリは、スワイプして閉じる機能をサポートしていません。
akohout 2015年

@raveN回答を更新しました。
Pierpaolo Paolini 2015年


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ページを参照してください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.