RecyclerViewでドラッグしてスワイプします。 パート1:ItemTouchHelper

RecyclerViewでドラッグしてスワイプします。パート1:ItemTouchHelper


RecyclerViewを使用したAndroidには、多くのチュートリアル、ライブラリ、 ドラッグアンドドロップスワイプして非表示の実装があります。 それらのほとんどは、非推奨のView.OnDragListenerとRoman Nurikが開発したSwipeToDismissアプローチをまだ使用しています。 新しい、より効果的な方法はすでに利用可能ですが。 最新のAPIを使用することはほとんどありません。多くの場合、 GestureDetectorsおよびonInterceptTouchEventまたはその他のより複雑な実装に依存しています。 実際、これらの関数をRecyclerViewに追加する非常に簡単な方法があります。 これには、Androidサポートライブラリの一部でもある1つのクラスのみが必要です。


ItemTouchHelper


ItemTouchHelperは強力なユーティリティであり、 RecyclerView ドラッグアンドドロップおよびスワイプして 閉じる 機能を追加するために必要なすべてを処理します。 このユーティリティは、 RecyclerView.ItemDecorationのサブクラスであり、既存のほぼすべてのLayoutManagerとアダプターに簡単に追加できます。 また、要素のアニメーションにも対応し、あるタイプの要素をリスト内の別の場所などにドラッグアンドドロップする機能を提供します。 この記事では、 ItemTouchHelper簡単な実装をItemTouchHelperます。 後で、この一連の記事の一部として、範囲を拡大し、他のオプションを検討します。


ご注意 結果をすぐに見たいですか? Github: Android-ItemTouchHelper-Demoをご覧ください。 最初のコミットはこの記事に関連しています。 デモの.apkファイルはここからダウンロードできます


例


カスタマイズ


最初にRecyclerViewを設定する必要があります。 まだ行っていない場合は、 build.gradleファイルにRecyclerView依存関係を追加します。


 compile 'com.android.support:recyclerview-v7:22.2.0' 

ItemTouchHelperはほぼすべてのRecyclerView.AdapterおよびLayoutManagerで動作しますが、この記事はこれらのファイルを使用した例に基づいています


ItemTouchHelperとItemTouchHelper.Callbackを使用する


ItemTouchHelperを使用するには、 ItemTouchHelperを作成する必要があります。 これは、動き( eng。Move )とスワイプ( eng。Swipe )を追跡できるインターフェースです。 さらに、ここでは、選択したviewコンポーネントの状態を制御し、デフォルトのアニメーションをオーバーライドできます。 基本実装SimpleCallbackを使用する場合に使用できるヘルパークラスがあります 。 しかし、これが実際にどのように機能するかを理解するために、私たちはすべて自分で行います。


ドラッグアンドドロップおよびスワイプして閉じるという基本的な機能を含めるために再定義する必要があるインターフェイスの主な機能:


 getMovementFlags(RecyclerView, ViewHolder) onMove(RecyclerView, ViewHolder, ViewHolder) onSwiped(ViewHolder, int) 

また、いくつかのヘルパーメソッドを使用します。


 isLongPressDragEnabled() isItemViewSwipeEnabled() 

それらを一つ一つ考えてみましょう。


 @Override public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN; int swipeFlags = ItemTouchHelper.START | ItemTouchHelper.END; return makeMovementFlags(dragFlags, swipeFlags); } 

ItemTouchHelperすると、イベントの方向を簡単に判断できます。 getMovementFlags()メソッドをオーバーライドして、ドラッグアンドドロップする方向がサポートされることを示す必要があります。 リターンフラグを作成するには、ヘルパーメソッドItemTouchHelper.makeMovementFlags(int, int)ます。 この例では、両方向のドラッグアンドドロップを有効にします。


 @Override public boolean isLongPressDragEnabled() { return true; } 

ItemTouchHelperは、スワイプ機能なしのドラッグアンドドロップ(またはその逆)でのみ使用できるため、サポートする機能を正確に指定する必要があります。 isLongPressDragEnabled()メソッドは、 RecyclerView要素を長isLongPressDragEnabled()後のドラッグアンドドロップをサポートするためにtrueを返す必要があります。 または、 ItemTouchHelper.startDrag(RecyclerView.ViewHolder)メソッドを呼び出して、手動でドラッグを開始できます。 このオプションは後で検討します。


 @Override public boolean isItemViewSwipeEnabled() { return true; } 

viewコンポーネント内の任意の場所に触れた後にホイップを有効にするには、 isItemViewSwipeEnabled()メソッドからtrueを返すだけです。 または、 ItemTouchHelper.startSwipe(RecyclerView.ViewHolder)メソッドを呼び出して、スワイプを手動で開始できます。


データの更新を通知するには、次の2つのメソッドonMove()およびonSwiped()が必要です。 そのため、最初に、これらのイベントを一連の呼び出しに沿って送信できるようにするインターフェイスを作成します。


ItemTouchHelperAdapter.java


 public interface ItemTouchHelperAdapter { void onItemMove(int fromPosition, int toPosition); void onItemDismiss(int position); } 

これを行う最も簡単な方法は、 RecyclerListAdapterにリスナーを実装させることです。


 public class RecyclerListAdapter extends RecyclerView.Adapter<ItemViewHolder> implements ItemTouchHelperAdapter { // ...   [](https://gist.github.com/iPaulPro/2216ea5e14818056cfcc#file-recyclerlistadapter-java) @Override public void onItemDismiss(int position) { mItems.remove(position); notifyItemRemoved(position); } @Override public boolean onItemMove(int fromPosition, int toPosition) { if (fromPosition < toPosition) { for (int i = fromPosition; i < toPosition; i++) { Collections.swap(mItems, i, i + 1); } } else { for (int i = fromPosition; i > toPosition; i--) { Collections.swap(mItems, i, i - 1); } } notifyItemMoved(fromPosition, toPosition); return true; } 

アダプターが変更を認識できるように、 notifyItemRemoved()およびnotifyItemMoved()メソッドを呼び出すことが非常に重要です。 また、 viewコンポーネントが新しいインデックスに移動するたびに要素の位置を変更することに注意してください。 移動の最後(「ドロップ」イベント)ではありません


onMove()およびonSwiped()メソッドをオーバーライドする必要があるため、 SimpleItemTouchHelperCallback作成に戻ることができます。 まず、アダプターのコンストラクターとフィールドを追加します。


 private final ItemTouchHelperAdapter mAdapter; public SimpleItemTouchHelperCallback( ItemTouchHelperAdapter adapter) { mAdapter = adapter; } 

次に、残りのイベントを再定義し、これをアダプターに報告します。


 @Override public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) { mAdapter.onItemMove(viewHolder.getAdapterPosition(), target.getAdapterPosition()); return true; } @Override public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) { mAdapter.onItemDismiss(viewHolder.getAdapterPosition()); } 

その結果、 Callbackクラスは次のようになります。


 public class SimpleItemTouchHelperCallback extends ItemTouchHelper.Callback { private final ItemTouchHelperAdapter mAdapter; public SimpleItemTouchHelperCallback(ItemTouchHelperAdapter adapter) { mAdapter = adapter; } @Override public boolean isLongPressDragEnabled() { return true; } @Override public boolean isItemViewSwipeEnabled() { return true; } @Override public int getMovementFlags(RecyclerView recyclerView, ViewHolder viewHolder) { int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN; int swipeFlags = ItemTouchHelper.START | ItemTouchHelper.END; return makeMovementFlags(dragFlags, swipeFlags); } @Override public boolean onMove(RecyclerView recyclerView, ViewHolder viewHolder, ViewHolder target) { mAdapter.onItemMove(viewHolder.getAdapterPosition(), target.getAdapterPosition()); return true; } @Override public void onSwiped(ViewHolder viewHolder, int direction) { mAdapter.onItemDismiss(viewHolder.getAdapterPosition()); } } 

コールバックの準備ができたら、 ItemTouchHelperを作成してattachToRecyclerView(RecyclerView)メソッドを呼び出すことができます(たとえば、 MainFragment.javaで )。


 ItemTouchHelper.Callback callback = new SimpleItemTouchHelperCallback(adapter); ItemTouchHelper touchHelper = new ItemTouchHelper(callback); touchHelper.attachToRecyclerView(recyclerView); 

開始後、次のようなものが表示されます。


結果


おわりに


これは、 ItemTouchHelper最も単純化された実装です。 ただし、サードパーティのライブラリを使用して、 RecyclerView標準のドラッグアンドドロップおよびスワイプしてRecyclerView アクションを実装する必要がないことに気付くかもしれません。 次の部分では、ドラッグアンドドロップ時の要素の外観にさらに注意を払います。


ソースコード


GitHubでプロジェクトを作成し、このシリーズの記事で取り上げられていることを実証しました: Android-ItemTouchHelper-Demo最初のコミットは主にこの部分と2番目に少し関連します。


→RecyclerViewでドラッグしてスワイプします。 パート2:コントローラー、グリッド、およびカスタムアニメーションのドラッグアンドドロップ



Source: https://habr.com/ru/post/J427681/


All Articles