
最初の部分では、 ItemTouchHelperとItemTouchHelper.Callbackの実装を確認しました 。これは、基本的なドラッグアンドドロップおよびスワイプして 閉じる 機能をRecyclerView追加します 。 この記事では、グリッド、ドラッグアンドドロップコントローラー、リストアイテムの選択、カスタムスワイプアニメーションの形式での要素の配置のサポートを追加することで、前の記事で行ったことを継続します。

ドラッグアンドドロップコントローラー
ドラッグ&ドロップをサポートするリストを作成する場合、通常、アイテムをタッチでドラッグアンドドロップする機能を実装します。 これは、「編集モード」でのリストの明快さと使いやすさに貢献しており、重要なガイドラインでも推奨されています。 この例にドラッグアンドドロップコントローラーを追加するのは非常に簡単です。

まず、要素( item_main.xml )のlayout更新しlayout 。
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/item" android:layout_width="match_parent" android:layout_height="?listPreferredItemHeight" android:clickable="true" android:focusable="true" android:foreground="?selectableItemBackground"> <TextView android:id="@+id/text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:layout_marginLeft="16dp" android:textAppearance="?android:attr/textAppearanceMedium" /> <ImageView android:id="@+id/handle" android:layout_width="?listPreferredItemHeight" android:layout_height="match_parent" android:layout_gravity="center_vertical|right" android:scaleType="center" android:src="@drawable/ic_reorder_grey_500_24dp" /> </FrameLayout>
ドラッグコントローラーに使用される画像は、 マテリアルデザインアイコンにあり、Android Studioの便利なアイコンジェネレータープラグインを使用してプロジェクトに追加できます 。
前の記事で簡単に説明したように、 ItemTouchHelper.startDrag(ViewHolder)を使用して、プログラムでドラッグアンドドロップを開始できます。 したがって、必要なことは、ドラッグコントローラーを追加してViewHolder更新し、 startDrag()を呼び出す単純なタッチハンドラーを設定することだけです。
チェーンに沿ってイベントを渡すためのインターフェースが必要になります。
public interface OnStartDragListener { void onStartDrag(RecyclerView.ViewHolder viewHolder); }
次に、 ItemViewHolderドラッグコントローラーのImageViewを定義します。
public final ImageView handleView; public ItemViewHolder(View itemView) { super(itemView);
そして、 RecyclerListAdapterを更新します。
private final OnStartDragListener mDragStartListener; public RecyclerListAdapter(OnStartDragListener dragStartListener) { mDragStartListener = dragStartListener;
RecyclerListAdapterは次のようになります 。
OnStartDragListenerは、 OnStartDragListenerをフラグメントに追加するOnStartDragListenerです。
public class RecyclerListFragment extends Fragment implements OnStartDragListener {
RecyclerListFragmentは、次のようになります 。 これで、アプリケーションを起動すると、コントローラーにタッチしてドラッグアンドドロップを開始できます。

リストアイテムの強調表示
この例では、ドラッグされているアイテムの視覚的な表示はありません。 これは当然のことではありませんが、修正は簡単です。 ItemTouchHelperを使用すると、標準のアイテム強調表示効果を使用できます。 Lollipop以降のAndroidバージョンでは、要素とのやり取りの過程でバックライトが要素に「広がり」ます。 以前のバージョンでは、要素の色が暗くなりました。
この例を実装するにFrameLayout要素のルートFrameLayout背景( backgroundプロパティ)を追加するか、 RecyclerListAdapter.ItemViewHolderコンストラクターで設定します。 次のようになります。

見た目はかっこいいですが、さらに制御したい場合があります。 これを行う1つの方法は、 ViewHolder要素の状態変更ViewHolder処理できるようにすることViewHolder 。 このため、 ItemTouchHelper.Callbackはさらに2つのメソッドを提供します。
それでは、すべてをまとめましょう。
最初に、 ViewHoldersが実装するインターフェイスを作成します。
public interface ItemTouchHelperViewHolder { void onItemSelected(); void onItemClear(); }
次に、 SimpleItemTouchHelperCallback 、適切なメソッドを実装します。
@Override public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
今残っているのは、 RecyclerListAdapter.ItemViewHolder ItemTouchHelperViewHolder RecyclerListAdapter.ItemViewHolder実装RecyclerListAdapter.ItemViewHolderことItemTouchHelperViewHolderです:
public class ItemViewHolder extends RecyclerView.ViewHolder implements ItemTouchHelperViewHolder {
この例では、要素がアクティブなときに灰色の背景を追加してから削除します。 ItemTouchHelperとアダプターが密接に接続されている場合、この設定を簡単に破棄し、 ItemTouchHelper.Callback viewコンポーネントの状態を直接切り替えることができます。
ネット
GridLayoutManagerを使用しようとすると、正しく動作しないことがわかります。 理由と解決策は簡単です。アイテムの左右へのドラッグをサポートすることをItemTouchHelperに伝える必要があります。 SimpleItemTouchHelperCallback前半で、既に指定しました:
@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); }
グリッドをサポートするために必要な唯一の変更は、適切なフラグを追加することです。
int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;
ただし、 スワイプしてswipeFlags 、グリッド要素の自然な動作ではないため、 swipeFlagsほとんどswipeFlagsます。
@Override public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN | ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT; int swipeFlags = 0; return makeMovementFlags(dragFlags, swipeFlags); }
動作するGridLayoutManager例を確認するには、 RecyclerGridFragmentを参照してください。 起動時の外観は次のとおりです。

カスタムスワイプアニメーション
ItemTouchHelper.Callbackは、ドラッグアンドドロップ中にアニメーションを完全に制御するための非常に便利な方法を提供します。 ItemTouchHelperはRecyclerView.ItemDecorationであるため、同様の方法でviewコンポーネントをレンダリングするプロセスに介入できます。 次のパートでは、この質問をさらに詳しく調べますが、ここでは、デフォルトのスワイプアニメーションをオーバーライドして線形消失を示す簡単な例を見てみましょう。
@Override public void onChildDraw(Canvas c, RecyclerView recyclerView, ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) { if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE) { float width = (float) viewHolder.itemView.getWidth(); float alpha = 1.0f - Math.abs(dX) / width; viewHolder.itemView.setAlpha(alpha); viewHolder.itemView.setTranslationX(dX); } else { super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive); } }
dXおよびdYは、選択したviewコンポーネントに対する現在のシフトです。ここで、
- -1.0fは、右から左への
ItemTouchHelper.START ( ItemTouchHelper.ENDからItemTouchHelper.ENDへ) - 1.0fは左から右へ完全にスワイプします(
ItemTouchHelper.STARTからItemTouchHelper.STARTへ)
デフォルトのアニメーションをトリガーするには、処理していないactionStateに対してsuperを呼び出すことが重要です。
次のパートでは、ドラッグアンドドロップ時に要素の描画を制御する例を検討します。
おわりに
実際、ItemTouchHelperのセットアップはとても楽しいです。 この記事の量を増やしないために、私はそれをいくつかに分けました。
ソースコード
Android-ItemTouchHelper-Demo GitHubリポジトリでこの記事シリーズの完全なコードを参照してください。 この記事では、 ef8f149からd164fbaへのコミットについて説明します 。
←RecyclerViewでドラッグしてスワイプします。 パート1:ItemTouchHelper