DropHelper
クラスを使用すると、ドラッグ&ドロップ機能の実装が簡単になります。Jetpack の DragAndDrop
ライブラリのメンバーである DropHelper
は、API レベル 24 までの下位互換性を提供しています。
DropHelper
によって、ドロップ ターゲットの指定、ドロップ ターゲットのハイライト表示のカスタマイズ、ドロップされたデータの処理方法の定義が可能です。
ドラッグのソースを設定
まず、ドラッグ ソースビューと OnDragStartListener
を使用して DragStartHelper
を作成します。
OnDragStartListener
で、onDragStart()
メソッドをオーバーライドします。移動するデータの ClipData
オブジェクトと ClipData.Item
オブジェクトを作成します。ClipData
の一部として、ClipData
内の ClipDescription
オブジェクトに格納されているメタデータを指定します。データの移動を表していないドラッグ&ドロップ オペレーションの場合は、実際のオブジェクトの代わりに null
を使用することをおすすめします。
Kotlin
DragStartHelper(draggableView) { view: View, _: DragStartHelper -> val item = ClipData.Item(view.tag as? CharSequence) val dragData = ClipData( view.tag as? CharSequence, arrayOf(ClipDescription.MIMETYPE_TEXT_PLAIN), item ) view.startDragAndDrop( dragData, View.DragShadowBuilder(view), null, 0 ) }.attach()
Java
new DragStartHelper(draggableView, new DragStartHelper.OnDragStartListener() { @Override public void onDragStart(View view, DragStartHelper helper) { CharSequence tag = (CharSequence) view.getTag(); ClipData.Item item = new ClipData.Item(tag); ClipData dragData = new ClipData( tag, new String[]{ClipDescription.MIMETYPE_TEXT_PLAIN}, item); view.startDragAndDrop( dragData, new View.DragShadowBuilder(view), null, 0); } });
ドロップ ターゲットを指定する
ユーザーがビューの上にドロップ シャドウを解放するときは、データを受け取って正しく応答するように、ビューを適切に構成する必要があります。
DropHelper.configureView()
は、ドロップ ターゲットを指定できる静的なオーバーロード メソッドです。パラメータには次のものがあります。
- 現在の
Activity
- URI 権限に使用されます。 - ドロップ ターゲットの構成オプション(特に埋め込み
EditText
フィールドのリスト)。 - ドロップされたデータを処理するための
OnReceiveContentListener
。
たとえば、画像を受け入れるドロップ ターゲットを作成するには、次のいずれかのメソッド呼び出しを使用します。
Kotlin
configureView( myActivity, targetView, arrayOf("image/*"), options, onReceiveContentListener) // or configureView( myActivity, targetView, arrayOf("image/*"), onReceiveContentListener)
Java
DropHelper.configureView( myActivity, targetView, new String[] {"image/*"}, options, onReceiveContentlistener); // or DropHelper.configureView( myActivity, targetView, new String[] {"image/*"}, onReceiveContentlistener);
2 番目の呼び出しでは、ドロップ ターゲットの設定オプションが省略されています。この場合、ドロップ ターゲットのハイライト カラーはテーマのセカンダリ(アクセント カラー)に設定され、ハイライトの角の丸みは 16 dp に設定され、EditText
コンポーネントのリストは空になります。詳しくは、次のセクションをご覧ください。
ドロップ ターゲットを構成する
DropHelper.Options
内部クラスを使用すると、ドロップ ターゲットを構成できます。クラスのインスタンスを DropHelper.configureView(Activity, View, String[], Options,
OnReceiveContentListener
) メソッドに渡します。詳しくは、前のセクションをご覧ください。
ドロップ ターゲットのハイライト表示をカスタマイズする
DropHelper
は、ユーザーがターゲット上にコンテンツをドラッグしたときにハイライト表示されるように、ドロップ ターゲットを設定します。DropHelper
はデフォルトのスタイルを提供し、DropHelper.Options
はハイライトの色を設定し、ハイライトの長方形の角の半径を指定します。
次の例に示すように、DropHelper.Options.Builder
クラスを使用して DropHelper.Options
インスタンスを作成し、構成オプションを設定します。
Kotlin
val options: DropHelper.Options = DropHelper.Options.Builder() .setHighlightColor(getColor(R.color.purple_300)) .setHighlightCornerRadiusPx(resources.getDimensionPixelSize(R.dimen.drop_target_corner_radius)) .build()
Java
DropHelper.Options options = new DropHelper.Options.Builder() .setHighlightColor(getColor(R.color.purple_300)) .setHighlightCornerRadiusPx(getResources().getDimensionPixelSize(R.dimen.drop_target_corner_radius)) .build();
ドロップ ターゲットの EditText コンポーネントを処理する
DropHelper
は、ターゲットに編集可能なテキスト フィールドが含まれている場合、ドロップ ターゲット内のフォーカスも制御します。
ドロップ ターゲットは単一のビューまたはビュー階層のいずれかです。ドロップ ターゲットのビュー階層に 1 つ以上の EditText
コンポーネントが含まれている場合は、コンポーネントのリストを DropHelper.Options.Builder.addInnerEditTexts(EditText...)
に渡して、ドロップ ターゲットのハイライト表示とテキストデータ処理が正しく機能するようにします。
DropHelper
は、ドロップ ターゲットのビュー階層内の EditText
コンポーネントが、ドラッグ操作中に、含まれているビューからフォーカスを盗むのを防ぎます。
また、ドラッグ&ドロップ ClipData
にテキストと URI データが含まれている場合、DropHelper
は、ドロップ ターゲットの EditText
コンポーネントのいずれかを選択してテキストデータを処理します。選択は、次の優先順位に基づいて行われます。
ClipData
がドロップされるEditText
。- テキスト カーソル(キャレット)を含む
EditText
。 DropHelper.Options.Builder.addInnerEditTexts(EditText...)
の呼び出しに指定された最初のEditText
。
EditText
をデフォルトのテキストデータ ハンドラとして設定するには、DropHelper.Options.Builder.addInnerEditTexts(EditText...)
の呼び出しの最初の引数として EditText
を渡します。たとえば、ドロップ ターゲットで画像を処理できるものの、編集可能なテキスト フィールド T1
、T2
、T3
が含まれている場合は、次のようにして T2
をデフォルトにします。
Kotlin
val options: DropHelper.Options = DropHelper.Options.Builder() .addInnerEditTexts(T2, T1, T3) .build()
Java
DropHelper.Options options = new DropHelper.Options.Builder() .addInnerEditTexts(T2, T1, T3) .build();
ドロップ ターゲットのデータを処理する
DropHelper.configureView()
メソッドは、ドラッグ&ドロップの ClipData
を処理するために作成した OnReceiveContentListener
を受け入れます。ドラッグ&ドロップ データは、ContentInfoCompat
オブジェクトでリスナーに提供されます。オブジェクト内にテキストデータが存在します。画像などのメディアは URI で表されます。
OnReceiveContentListener
は、DropHelper.configureView()
を使用して次のタイプのビューを構成した場合、ドラッグ&ドロップ以外のユーザー操作(コピーして貼り付けなど)によってドロップ ターゲットに渡されるデータも処理します。
- すべてのビュー(ユーザーが Android 12 以降を実行している場合)。
AppCompatEditText
(Android 7.0 より前のバージョンの Android を使用している場合)。
MIME タイプ、権限、コンテンツの検証
DropHelper
による MIME タイプの確認は、ドラッグ&ドロップ データを提供するアプリが作成するドラッグ&ドロップ ClipDescription
に基づいています。ClipDescription
を検証して、MIME タイプが正しく設定されていることを確認します。
DropHelper
は、ドラッグ&ドロップ ClipData
に含まれるコンテンツ URI に対するすべてのアクセス権をリクエストします。詳細については、DragAndDropPermissions
をご覧ください。この権限により、ドラッグ&ドロップ データを処理するときにコンテンツ URI を解決できます。
DropHelper
は、ドロップされたデータの URI を解決する際に、コンテンツ プロバイダから返されたデータを検証しません。null をチェックし、解決されたデータの正確性を検証します。