简化拖放操作的 DropHelper

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() 是一个静态的重载方法,允许您指定放置目标。其参数包括以下内容

例如,要创建接受图像的放置目标,可以使用以下方法调用之一

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 组件来处理文本数据。选择基于以下优先级顺序

  1. 放置 ClipDataEditText
  2. 包含文本光标(插入符)的 EditText
  3. 提供给 DropHelper.Options.Builder.addInnerEditTexts(EditText...) 调用的第一个 EditText

要将 EditText 设置为默认文本数据处理程序,请将 EditText 作为对 DropHelper.Options.Builder.addInnerEditTexts(EditText...) 的调用的第一个参数传递。例如,如果您的放置目标处理图像但包含可编辑文本字段 T1T2T3,请按如下方式将 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 表示。

OnReceiveContentListener 还处理用户通过拖放以外的交互(如复制和粘贴)提供给放置目标的数据,当 DropHelper.configureView() 用于配置以下类型的视图时

  • 如果用户运行 Android 12 或更高版本,则所有视图。
  • AppCompatEditText,如果用户运行 Android 7.0 及更高版本。

MIME 类型、权限和内容验证

DropHelper执行的MIME类型检查基于拖放ClipDescription,该对象由提供拖放数据的应用创建。验证ClipDescription以确保MIME类型设置正确。

DropHelper请求拖放ClipData中包含的所有内容URI的访问权限。有关更多信息,请参阅DragAndDropPermissions。这些权限允许您在处理拖放数据时解析内容URI。

DropHelper在解析已放置数据中的URI时,不会验证内容提供程序返回的数据。检查空值并验证任何已解析数据的正确性。