DropHelper
类可简化拖放功能的实现。DropHelper
是 Jetpack DragAndDrop
库的成员,可向后兼容至 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);
第二个调用省略了拖放目标配置选项,在这种情况下,拖放目标突出显示颜色会设置为主题的次要(或强调色)颜色,突出显示圆角半径会设置为 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
还会控制拖放目标中的焦点。
拖放目标可以是单个视图,也可以是视图层次结构。如果拖放目标视图层次结构包含一个或多个 EditText
组件,请向 DropHelper.Options.Builder.addInnerEditTexts(EditText...)
提供组件列表,以确保拖放目标突出显示和文本数据处理正常运行。
DropHelper
可防止拖放目标视图层次结构中的 EditText
组件在拖动互动期间从包含视图窃取焦点。
此外,如果拖放操作 ClipData
包含文本和 URI 数据,DropHelper
会选择拖放目标中的一个 EditText
组件来处理文本数据。选择时遵循以下优先顺序:
- 放置
ClipData
的EditText
。 - 包含文本光标(脱字符号)的
EditText
。 - 为调用
DropHelper.Options.Builder.addInnerEditTexts(EditText...)
提供的第一个EditText
。
如需将 EditText
设为默认的文本数据处理程序,请将 EditText
作为调用 DropHelper.Options.Builder.addInnerEditTexts(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 表示。
当使用 DropHelper.configureView()
配置以下类型的视图时,OnReceiveContentListener
还会处理由拖放以外的用户互动(如复制和粘贴)提供给拖放目标的数据:
- 所有视图(如果用户搭载的是 Android 12 或更高版本)。
AppCompatEditText
(如果用户运行的是最低 Android 7.0 的 Android 版本)。
MIME 类型、权限和内容验证
DropHelper
进行的 MIME 类型检查是基于提供拖放数据的应用创建的拖放 ClipDescription
。请验证 ClipDescription
,确保 MIME 类型设置正确。
DropHelper
会请求对拖放操作 ClipData
中包含的内容 URI 的所有访问权限。如需了解详情,请参阅 DragAndDropPermissions
。利用这些权限,您可以在处理拖放数据时解析内容 URI。
在解析用户放下的数据中的 URI 时,DropHelper
不会验证 content provider 返回的数据。检查是否存在 null,并验证所有已解析数据的正确性。