DropHelper para simplificar la acción de arrastrar y soltar

La clase DropHelper simplifica la implementación de las capacidades de arrastrar y soltar. Un miembro de la biblioteca DragAndDrop de Jetpack, DropHelper, proporciona retrocompatibilidad hasta el nivel de API 24.

Usa DropHelper para especificar destinos para soltar, personalizar el resaltado de objetivos de soltar y definir cómo se controlan los datos descartados.

Establecer fuente de arrastre

Para comenzar, crea DragStartHelper con la vista de arrastre de fuente y OnDragStartListener.

En OnDragStartListener, anula el método onDragStart(). Crea un objeto ClipData y un objeto ClipData.Item para los datos que se moverán. Como parte de ClipData, proporciona metadatos que se almacenen en un objeto ClipDescription dentro de ClipData. Para una operación de arrastrar y soltar que no represente movimiento de datos, te recomendamos que uses null en lugar de un objeto real.

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);
    }
});

Cómo especificar destinos para soltar

Cuando un usuario lanza una sombra paralela sobre una vista, esta debe configurarse de forma correcta para aceptar los datos y responder correctamente.

DropHelper.configureView() es un método estático y sobrecargado que te permite especificar destinos para soltar. Sus parámetros incluyen lo siguiente:

Por ejemplo, a fin de crear un destino para soltar que acepte imágenes, usa cualquiera de las siguientes llamadas a métodos:

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);

En la segunda llamada, se omiten las opciones de configuración del destino para soltar, en cuyo caso el color de resaltado del destino para soltar se establece en el color secundario (o de elementos destacados) del tema, el radio de la esquina de resaltado se establece en 16 dp y la lista de componentes EditText está vacía. Consulta la siguiente sección para obtener más detalles.

Configura destinos para soltar

La clase interna DropHelper.Options te permite configurar destinos para soltar. Proporciona una instancia de la clase al método DropHelper.configureView(Activity, View, String[], Options, OnReceiveContentListener). Consulta la sección anterior para obtener más información.

Personaliza el resaltado del destino para soltar

DropHelper configura los destinos para soltar de manera que muestren una selección a medida que los usuarios arrastran contenido sobre los destinos. DropHelper proporciona un estilo predeterminado, y DropHelper.Options te permite establecer el color del destacado y especificar el radio de la esquina del rectángulo destacado.

Usa la clase DropHelper.Options.Builder para crear una instancia de DropHelper.Options y establece las opciones de configuración, como se muestra en el siguiente ejemplo:

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();

Cómo controlar componentes de EditText en destinos para soltar

DropHelper también controla el enfoque dentro del destino para soltar cuando el destino contiene campos de texto editables.

Los destinos para soltar pueden ser una sola vista o una jerarquía de vistas. Si la jerarquía de vistas del destino para soltar contiene uno o más componentes EditText, proporciona una lista de los componentes a DropHelper.Options.Builder.addInnerEditTexts(EditText...) a fin de asegurarte de que el resaltado del destino para soltar y el manejo de datos de texto funcionen correctamente.

DropHelper evita que los componentes EditText dentro de la jerarquía de vistas del destino para soltar roben el enfoque de la vista contenedora durante las interacciones de arrastre.

Además, si la función de arrastrar y soltar ClipData incluye datos de texto y URI, DropHelper selecciona uno de los componentes EditText en el destino para soltar a fin de controlar los datos de texto. La selección se basa en el siguiente orden de prioridad:

  1. El EditText en el que se descarta el ClipData.
  2. El EditText que contiene el cursor de texto (signo de intercalación).
  3. El primer EditText proporcionado a la llamada a DropHelper.Options.Builder.addInnerEditTexts(EditText...).

Para establecer un elemento EditText como el controlador de datos de texto predeterminado, pasa EditText como el primer argumento de la llamada a DropHelper.Options.Builder.addInnerEditTexts(EditText...). Por ejemplo, si tu objetivo de soltar controla las imágenes, pero contiene campos de texto editables T1, T2 y T3, haz que T2 sea el valor predeterminado de la siguiente manera:

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();

Maneja datos en destinos para soltar

El método DropHelper.configureView() acepta un OnReceiveContentListener que creas para controlar la función de arrastrar y soltar ClipData. Los datos de la función de arrastrar y soltar se proporcionan al objeto de escucha en un objeto ContentInfoCompat. Los datos de texto están presentes en el objeto. El contenido multimedia, como las imágenes, está representado por URIs.

OnReceiveContentListener también controla los datos que proporcionan al destino para soltar las interacciones del usuario que no son de arrastrar y soltar, como copiar y pegar, cuando DropHelper.configureView() se usa para configurar los siguientes tipos de vistas:

  • Todas las vistas, si el usuario ejecuta Android 12 o una versión posterior
  • AppCompatEditText, si el usuario ejecuta una versión de Android anterior a la 7.0

Tipos de MIME, permisos y validación de contenido

La verificación del tipo de MIME por parte de DropHelper se basa en la función de arrastrar y soltar ClipDescription, que crea la app que proporciona los datos de arrastrar y soltar. Valida ClipDescription para asegurarte de que los tipos de MIME estén configurados correctamente.

DropHelper solicita todos los permisos de acceso para los URI de contenido que se encuentran en la función ClipData de arrastrar y soltar. Para obtener más información, consulta DragAndDropPermissions. Los permisos te permiten resolver los URI de contenido cuando procesas los datos de arrastrar y soltar.

DropHelper no valida los datos que muestran los proveedores de contenido cuando resuelven URI en los datos soltados. Comprueba la nulabilidad y la precisión de los datos resueltos.