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);
第二个调用省略了放置目标配置选项,在这种情况下,放置目标的高亮颜色将设置为主题的辅助(或强调色),高亮圆角半径设置为 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()
方法接受您创建的 OnReceiveContentListener
来处理拖放 ClipData
。拖放数据以 ContentInfoCompat
对象形式提供给监听器。文本数据在该对象中存在。媒体(如图片)以 URI 表示。
当使用 DropHelper.configureView()
配置以下类型的视图时,OnReceiveContentListener
也会处理用户通过除拖放之外的交互(例如复制和粘贴)提供给放置目标的数据:
- 所有视图,如果用户运行 Android 12 或更高版本。
AppCompatEditText
,如果用户运行的 Android 版本低至 Android 7.0。
MIME 类型、权限和内容验证
DropHelper
的 MIME 类型检查基于由提供拖放数据的应用创建的拖放 ClipDescription
。验证 ClipDescription
以确保 MIME 类型设置正确。
DropHelper
请求拖放 ClipData
中包含的内容 URI 的所有访问权限。有关更多信息,请参阅 DragAndDropPermissions
。权限允许您在处理拖放数据时解析内容 URI。
DropHelper
在解析已放置数据中的 URI 时,不验证内容提供程序返回的数据。请检查是否为 null,并验证任何已解析数据的正确性。