Drag and drop android это

Технология Drag and Drop в Android

Недавно у меня появилась идея заняться разработкойигры для андроид. Для начала я решил написать шахматы. Мне казалось технологияDrag and Drop отлично подойдет для реализации механизма перемещения фигур. Для непосвященных отмечу, чтометод drag and drop заключается в возможности перетаскивания одних графических объектов на другие и выполнения того или иного действия после отпускания. Простейший пример — удаление ярлыка с рабочего стола вашего ПК перетаскиванием его в корзину. «Кинув» ярлык в корзину, мы говорим системе, что хотим заставить взаимодействовать эти два объекта. Система получает наш сигнал и решает, какое действие ей стоит предпринять. Drag and drop получила широкое распространение благодаря своей интуитивной ясности. Этот подход подкреплен нашим опытом взаимодействия с объектами реального мира и прекрасно работает в виртуальной среде. Что же касается шахмат, с помощью drag and drop технологически проще определить клетку, куда пользователь перетащил фигуру, поскольку не нужно вычислять номер клетки по координатам точки отпускания. Эту работу возьмет на себя виртуальная машина.

Цели использования технологии Drag n Drop

Использование технологии drag and drop позволяет мне малой кровью решить три задачи:

  1. Визуализация хода. Когда пользователь касается фигуры и начинает ее перемещение по экрану, фигура заменяется более мелким рисунком. Таким образом, пользователь понимает что фигура захвачена.
  2. Я ограничил область перемещения фигуры размерами доски.
  3. Если пользователь отпустил фигуру в неправильном месте, она должна вернуться в первоначальное положение.

Задачи обозначены, приступим к их реализации.

Подмена ImageView при касании

Все мои фигуры представляют собой объекты ImageView. К сожалению, оказалось что реализация Drag & Drop в Android не позволяет «прямо из коробки» осуществлять подмену изображения объекта при его касании. Тем не менее, эта задача вполне решаема средствами API. Нам понадобится выполнить ряд несложных действий:

  1. Создать объект DragShadowBuilder.
  2. Вызвать метод startDrag.
  3. Спрятать наш ImageView, который отображает фигуру, вызвав метод setVisibility с параметром View.INVISIBLE. В результате на экране останется только объект DragShadowBuilder, что будет сигналом пользователю о захвате фигуры.

Эти действия необходимо реализовать в обработчике OnTouchListner объекта ImageView. Для этого переопределим метод onTouch:

Все очень просто. Итак, с подменой изображения разобрались, перейдем к следующей задаче.

Ограничение области перетаскивания для функции drag drop

Ограничение области перетаскивания связано с одной проблемой. Дело в том, что если отпустить фигуру за пределами доски, события drop не случится, поскольку пользователь отпустил объект на пустом месте, и объекту не с чем взаимодействовать. В результате фигура не вернется в свое первоначальное состояние и так и останется навсегда спрятанной. Я убил уйму времени на чтение документации, но так и не нашел способа ограничить область перетаскивания объектов. Озарение пришло внезапно. Мне совсем не нужно ограничивать область, мне нужно узнать правильно ли пользователь отпустил фигуру или нет.

Определение правильности отпускания
Ответы на свои вопросы я нашел в разделе «handling drag end events» на сайте Android Developers. Вот несколько ключевых моментов:

  1. Когда пользователь завершает перетаскивание в обработчике DragListeners генерируется событие ACTION_DRAG_ENDED.
  2. В DragListener можно получить более подробную информацию об операции drag, вызвав метод DragEvent.getResult().
  3. Если DragListener возвращает true в ответ на событие ACTION_DROP, вызов getResult также вернет true, в противном случае — false.

Таким образом, мне нужно перехватить событие ACTION_DRAG_ENDED и вызывать метод getResult. Если он вернет false, значит пользователь утащил фигуру за пределы доски, и мне нужно перевести ImageView в видимый режим.

Теперь пользователь может где угодно отпускать фигуру, и ничего страшного не произойдет.

Определение допустимых ходов

Последняя часть статьи посвящена проверке допустимости хода, который пытается сделать пользователь. Прежде чем подробно приступить к обсуждению этой темы, сделаю небольшую ремарку, объясняющую структуру моего приложения. Шахматная доска представлена как TableLayout, а каждая клетка является потомком LinearLayout и имеет OnDragListener.

Читайте также:  Как подключить sdr для андроид

Кроме того, каждый OnDragListener ссылается на объект «посредника» (mediator), который заботится о взаимодействии игровых объектов и запоминает положение текущей клетки.

Когда пользователь тащит фигуру над клеткой, возможны следующие действия:

  1. Использование события ACTION_DRAG_ENTERED для установки переменной ‘containsDraggable’ в true.
  2. Использование события ACTION_DRAG_EXITED для установки переменной ‘containsDraggable’ в false.
  3. Использование события ACTION_DROP для запроса посредника о допустимости установки фигуры в эту клетку.

Ниже приведен код, реализующий описанную логику

Как видите, не зависимо от того допустим ли ход или нет, ImageView переводится в видимое состояние. Я хотел, чтобы пользователь видел, как перемещается фигура. Ранее я упоминал, что клетка является потомком LayoutView. Это сделано для того чтобы проще перемещать ImageView от клетки к клетке. Ниже приводится код метода checkForValidMove, который показывает, как происходит перемещение ImageView.

Надеюсь, эта статья поможет Вам при разработке собственных проектов.

Источник

Находки программиста

Решения конкретных задач программирования. Java, Android, JavaScript, Flex и прочее. Настройка софта под Linux, методики разработки и просто размышления.

воскресенье, 15 июля 2012 г.

Реализация Drag and Drop в Android

Touch-интерфейсы дают нам удивительную возможность «прикоснуться к приложению», манипулировать с элементами на экране самым естественным для человека способом. И нам, разработчикам, грех не использовать такую возможность. Давайте разберёмся, как максимально просто реализовать Drag&Drop в нашем приложении.
В двух словах уточним, какое поведение элемента интерфейса мы хотим получить. Есть пара белых ImageView и один синий прямоугольник. Та из белых картинок, которой мы коснулись будет следовать за пальцем, пока мы её не отпустим. Если мы отпустим её над синим прямоугольником, прямоугольник станет красным, и картинка останется на месте. Если за пределами — картинка вернётся на исходную позицию.
Основная наша цель — сделать всё максимально просто. Кроме Layout-a, описывающего начальное состояние интерфейса, мы напишем всего один класс в сотню строк кода. Итак приступим.

Становимся в исходное положение

Как я и описывал в условии задачи: тут синий прямоугольник и две картинки в RelativeLayout-е. Ничего особенного.

Вот и наши 100 строк кода:

Посмотрим на наш код внимательнее. Вся логика реализована тут с помощью двух listener-ов. Первый OnTouchListener, метод onTouch которого реализует непосредственно наше Activity мы навешиваем на «подвижные» картинки. Задача, которую мы тут решаем — определить какая из картинок под пальцем, сохранить её начальные параметры расположения на случай, если нужно будет вернуться и установить флаг начала перемещения.
Второй OnTouchListener вешаем на самый верхний элемент иерархии View нашего Activity. Он определяет координаты «цели», перемещает картинку и проверяет, не попали ли мы уже в цель.

Источник

The Android Drag-and-Drop Framework in Practice

The Android drag-and-drop framework provides you with the tools necessary to create components that allow your users to move data around an app using drag-and-drop gestures. The framework contains an API for handling the drag-and-drop logic, such as drag events, listeners, etc. In this article, we’ll show how it all works and share an example that showcases how to make the API work with the UI.

API Overview

We’ll quickly go through the APIs and the components that we’ll need to create the example app. See the Drag and Drop section of the Android developers guide for the full documentation and more in-depth explanations.

States

A drag-and-drop action begins when a user performs a movement that the framework recognizes as a signal that data is being dragged. There are four steps (states) in the drag-and-drop process:

Started — Once your application’s logic decides that the user should perform a drag (for example, on a long press), you call startDrag() , which tells the system that the drag has started. After that, the system sends the ACTION_DRAG_STARTED event down to the drag event listeners for all the View objects in the current layout.

Читайте также:  Flash sms с андроида

Continuing — The user continues the drag, and the system now sends ACTION_DRAG_ENTERED or ACTION_DRAG_EXITED , depending on if the drag gesture entered or exited the bounds of the view to which the event is propagated.

Dropped — The user drops the dragged object/data, and the system sends the ACTION_DROP event to the listener of the view if the location of the drop event is inside that view’s bounding box.

End — The drag-and-drop operation has ended. All of the views that were listening for the drag-and-drop events now get the ACTION_DRAG_ENDED event.

These four states provide everything you need when it comes to updating the UI to match the drag-and-drop process and its result.

Listener and Callback Method

To receive the drag-and-drop events, the view needs to register a View.OnDragListener on the View via View#setOnDragListener() . The View.OnDragListener contains only one method, boolean onDrag(View v, DragEvent event) .

The first parameter you get in the onDrag() call is the view that received the event. The second parameter is the DragEvent object, which contains all the information about the particular drag-and-drop event, including the location of the event, the drag action (state), and the data it carries. See the full documentation for all the methods. We will see how to use this in the example at the end.

Drag-and-Drop Shadow

During the drag-and-drop action, the framework provides you with the API that enables you to draw on top of the dragged point, thus creating the visual representation of the dragged data. For that, you have to extend the View.DragShadowBuilder and pass it in the View#startDrag() method. When creating the View.DragShadowBuilder , you can pass a view that will be used as the basis of the drag gesture shadow.

To get and alter the coordinates of the drag-and-drop gesture, you need to override the onProvideShadowMetrics(Point outShadowSize, Point outShadowTouchPoint) method that gets you the size and the touch point, which you can then alter. They will then get propagated back to the system afterward. We’ll cover this more in the implementation.

The onDrawShadow(canvas: Canvas) method gives you a canvas that you can now use to draw the shadow.

The Example

There’s no point in going too deep with the documentation of components, so we’ll jump right into the action and create an example that will try to cover most of this API and showcase the real power of this framework. You can always go back and check the full documentation to see if there’s anything that you might need that’s not covered here.

We will create a sample app where you can pick colors from a palette of five colors.

For the sake of simplicity, the entire app will only have one view/activity, and that’s MainActivity . First we need to define a layout for it in the XML, namely activity_main.xml :

As you can see, we have two areas that we can paint: area1 and area2 . Then we have the floating action buttons, which we’ve used as color palette elements, so you can drag them into the areas to paint them in the same color as the dragged button. Of course, you can and probably should use custom views if you implement the color picker in your own app.

Now, let’s go to our MainActivity , where we will implement all of the drag-and-drop logic. In this particular example, we want to activate a drag action when one of the floating action buttons has been long pressed. Once the dragging has started, we will increase the shadow of the areas that can be painted, and once you hover over one of those areas, the shadow will grow even larger, in order to provide feedback that the area below will be painted if you drop the color.

Читайте также:  Books reader для андроид

First we define these elevation values in our MainActivity :

Since we will activate the drag action once one of the floating action buttons has been pressed, we need to create a long-press listener. A description for each line is in the comments:

Now, let’s create an OnDragListener that we will set on our areas:

In order to have some UI feedback, we’ll create a shadow for a drag gesture that will follow the finger. For that purpose, we extend View.DragShadowBuilder :

Lastly, we need to set the long-press listener on the floating action buttons and a drag listener on the areas that we can drop the color on:

And there we have it: We’ve implemented an example similar to what was shown earlier in this post. We hope this helps you better understand the process and see how you can implement the Android drag-and-drop framework for your own use case.

Conclusion

The Android drag-and-drop framework provides you with a flexible yet powerful API for dragging data across your app. It allows you to handle all of the stages in the drag-and-drop process in a very convenient way — both in terms of data and the UI.

Your app might need a custom solution, but in most of the drag-and-drop implementations, this API will be sufficient; you might just have to figure out the best way to set it up for your needs.

Источник

Использование Drag-and-drop между различными Activity в Android 7 Nougat

Описание технологии и разбор примера

Для передачи данных при перетаскивании используются классы ClipData и DragEvent. В приложении, в котором инициализируется операция перетаскивания, данные упаковываются с помощью ClipData. ClipData представляет собой сложный тип, содержащий в себе один или несколько экземпляров передаваемых данных. ClipData используется для размещения данных в буфере обмена. Для перетаскивания доступны следующие типы данных:

— MIMETYPE_TEXT_HTML: необходим для передачи HTML текста;
— MIMETYPE_TEXT_INTENT: необходим для передачи интента;
— MIMETYPE_TEXT_PLAIN: необходим для передачи обычного текста;
— MIMETYPE_TEXT_URILIST: необходим для передачи URL.

В приложении приемнике на соответствующем элементе интерфейса устанавливается слушатель перетаскивания, который принимает события DragEvent.

Давайте рассмотрим пример использования функции перетаскивания. В примере представлены два приложения: инициализатор (DragNDropExample) и приемник перетаскивания (DragNDropReceiver).

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

В приложении DragNDropExample реализовано перетаскивание изображения и текста. Файл изображения хранится в папке Downloads. При перетаскивании изображения другому процессу передается URI файла изображения. Инициализация перетаскивания происходит по долгому нажатию на соответствующие элементы.

Устанавливаем слушатель долгого нажатия.

Получаем URI файла для передачи другому процессу. В новой версии Android для получения доступа к файлам, размещенным в мультимедийных папках, необходимо использовать FileProvider.

Создаем объект ClipData и упаковываем в него URI. При создании объекта ClipData указывается тип упакованных данных. Тип MIMETYPE_TEXT_URILIST указывает, что упаковываютсяURI.

Инициализируем перетаскивание, передавая объект ClipData, объект dragShadowBuilder и устанавливая соответствующие флаги. Флаг View.DRAG_FLAG_GLOBAL разрешает перетаскивание между операциями. Флаги View.DRAG_FLAG_GLOBAL_URI_READ и View.DRAG_FLAG_GLOBAL_URI_WRITE разрешают соответственно чтение и запись URI. Для создания тени при перетаскивании используется DragShadowBuilder. В данном примере тенью является сам элемент интерфейса:

Аналогично происходит все для перетаскивания текста:

В приложении приемнике устанавливаются слушатели OnDragListener:

В слушателе задаются действия для определенных событий перетаскивания. В данном примере установлены действия для следующих событий:

— ACTION_DRAG_STARTED: перетаскивание начато;
— ACTION_DROP: пользователь отпустил перетаскиваемый элемент.

Для того чтобы вставка изображения производилась только в ImageView, а текста в TextView необходима соответствующая проверка. В данном участке кода проверяется тип перетаскиваемых данных и сравнивается с необходимым.

Для перетаскивания текста все происходит аналогично.

Ниже приведены скриншоты экрана в процессе перетаскивания

В процессе перетаскивания изображения:

После перетаскивания текста и изображения:

Заключение

Возможность перетаскивать информацию между различными процессами позволяет ускорить обмен данными между приложениями, сделать его более удобным и наглядным для пользователя.

Источник

Оцените статью