DropHelper для упрощенного перетаскивания

Класс DropHelper упрощает реализацию возможностей перетаскивания. DropHelper , являющийся членом библиотеки Jetpack DragAndDrop , обеспечивает обратную совместимость до уровня API 24.

Используйте DropHelper чтобы указать цели перетаскивания, настроить подсветку целей перетаскивания и определить, как обрабатываются перетаскиваемые данные.

Установить источник перетаскивания

Для начала создайте DragStartHelper с представлением источника перетаскивания и OnDragStartListener .

В OnDragStartListener переопределите метод onDragStart() . Создайте объект ClipData и объект ClipData.Item для перемещаемых данных. В рамках ClipData укажите метаданные, которые хранятся в объекте ClipDescription внутри ClipData . Для операции перетаскивания, которая не представляет перемещение данных, вы можете использовать null вместо реального объекта.

Котлин

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

Ява

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() — это статический перегруженный метод, позволяющий указывать цели перетаскивания. Его параметры включают в себя следующее:

Например, чтобы создать цель перетаскивания, которая принимает изображения, используйте любой из следующих вызовов метода:

Котлин

configureView(
    myActivity,
    targetView,
    arrayOf("image/*"),
    options,
    onReceiveContentListener)

// or

configureView(
    myActivity,
    targetView,
    arrayOf("image/*"),
    onReceiveContentListener)

Ява

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 и задать параметры конфигурации, как показано в следующем примере:

Котлин

val options: DropHelper.Options = DropHelper.Options.Builder()
                                      .setHighlightColor(getColor(R.color.purple_300))
                                      .setHighlightCornerRadiusPx(resources.getDimensionPixelSize(R.dimen.drop_target_corner_radius))
                                      .build()

Ява

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. EditText , в который перетаскиваются ClipData .
  2. EditText , содержащий текстовый курсор (курсор).
  3. Первый EditText , предоставленный для вызова DropHelper.Options.Builder.addInnerEditTexts(EditText...) .

Чтобы установить EditText в качестве обработчика текстовых данных по умолчанию, передайте EditText в качестве первого аргумента вызова DropHelper.Options.Builder.addInnerEditTexts(EditText...) . Например, если цель перетаскивания обрабатывает изображения, но содержит редактируемые текстовые поля T1 , T2 и T3 , сделайте T2 значением по умолчанию следующим образом:

Котлин

val options: DropHelper.Options = DropHelper.Options.Builder()
                                      .addInnerEditTexts(T2, T1, T3)
                                      .build()

Ява

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 до Android 7.0.

Типы MIME, разрешения и проверка контента

Проверка типа MIME с помощью DropHelper основана на перетаскивании ClipDescription , которое создается приложением, предоставляющим данные перетаскивания. Проверьте ClipDescription , чтобы убедиться, что типы MIME установлены правильно.

DropHelper запрашивает все разрешения на доступ к URI контента, содержащимся в перетаскиваемом ClipData . Дополнительные сведения см. в DragAndDropPermissions . Разрешения позволяют разрешать URI контента при обработке данных перетаскивания.

DropHelper не проверяет данные, возвращаемые поставщиками контента, при разрешении URI в удаленных данных. Проверьте наличие нуля и проверьте правильность всех разрешенных данных.