Drag and Drop technology in Android. Drag and drop technology How drag and drop is performed

Drag and Drop can help increase the performance of your iPad. Here's how you can use it.

So, you can move a file from one cloud storage service to another, copy text from Safari to a text editing app to add a quote, or back up certain photos in a file storage app.

How to drag and drop photos, files and text

1. Touch and hold a photo, file, or highlighted text that you want to drag into another application.

2. Drag the item to the desired location in this application or another that you opened in the "Slide Over" or "Split View" mode and release.

How to drag and drop multiple photos or files at the same time

1. Touch and hold one of the photos or files you want to drag.

2. While dragging the current item, tap another photo or file that you also want to drag. Do it again with as many items as you want to move.

3. Drag all the selected objects to the designated location in another application that you opened in Slide Over or Split View mode and release them.

How to drag text from one application to another

1. Touch and hold the part of the text you want to drag to select it.

2. Use the selection points to select the rest of the text that you want to drag.

3. Press and hold the highlighted text.

4. Drag the text into the application you want to place it in and release.

How to change the arrangement of icons of several applications at once using "Drag and Drop"

While most iOS drag and drop functionality only works on the iPad, this trick actually works on both the iPhone and iPad. This allows you to organize the arrangement of apps on your home screen using « Drag and Drop ”instead of moving them one by one.

1. Press and hold the icon of the application you want to reposition on the home screen.

2. Tap additional apps that you want to move as well.

3. Drag these apps to the page or folder where you want them to be and release them.

When it comes to the graphical user interface, one cannot but mention the technology Drag and drop (literally: Pull and Drop).

This technology is based on dragging and dropping GUI elements from source to destination. The interface is accessible only with a mouse (touchpad, trackball) or touch screen.

An element available for dragging is grabbed and held with the mouse, dragging it simultaneously to another place. When the mouse is in the correct position, the mouse button is released, releasing the object.

However, the Drag'n Drop interface should be distinguished from interface controls that have methods in their methods responsible for moving, which are implemented in the same way. For example, a window (form) has the ability to move around the screen (by dragging the title bar). ScrollBox has a scroll bar. But in both examples, dragging is an internal (for the component) action (event) and does not affect other objects in the system in any way.

The Drag and Drop interface is only applicable for moving an object from container to container, even if the containers are dissimilar. For example, dragging a file from folder to email.

Drag and Drop interface in web technologies

Using interfaces Drag and drop in web technologies was a breakthrough in. There are offline Drag and Drop editors (for example, DreamWeaver) and online (for example, any modern website builder.

Recently I had an idea to start developing a game for android. To begin with, I decided to write chess. I thought technology Drag and drop perfect for implementing a mechanism for moving shapes. For the uninitiated, I note that the drag and drop method is in the possibility of dragging some graphic objects onto others and performing an action after releasing. The simplest example is removing a shortcut from your PC desktop by dragging it to the trash can. By throwing a shortcut into the trash can, we tell the system that we want to force these two objects to interact. The system receives our signal and decides what action it should take. Drag and drop has become widespread due to its intuitive clarity. This approach is backed up by our experience with real world objects and works great in a virtual environment. As for chess, using drag and drop it is technologically easier to determine the cell where the user has dragged the piece, since there is no need to calculate the cell number from the coordinates of the drop point. The virtual machine will take over this work.

Purpose of using Drag n Drop technology

Using the drag and drop technology allows me to solve three problems with little blood:

  1. Visualization of the course. When the user taps a shape and starts moving it around the screen, the shape is replaced by a smaller drawing. Thus, the user understands that the figure is captured.
  2. I limited the area of \u200b\u200bmovement of the shape to the size of the board.
  3. If the user released the shape in the wrong place, it should return to its original position.

The tasks are outlined, let's get down to their implementation.

Swap ImageView on touch

All my shapes are ImageView objects. Unfortunately, it turned out that the implementation of Drag & Drop in Android does not allow "out of the box" to replace the image of an object when it is touched. Nevertheless, this task is quite solvable by means of API. We need to perform a number of simple steps:

  1. Create DragShadowBuilder object.
  2. Call startDrag method.
  3. Hide our ImageView that displays the shape by calling the setVisibility method with the View.INVISIBLE parameter. As a result, only the DragShadowBuilder object will remain on the screen, which will signal the user to grab the shape.

These actions must be implemented in the OnTouchListner handler of the ImageView. To do this, we will override the onTouch method:

@ Override public boolean onTouch (View view, MotionEvent motionEvent) (if (motionEvent. GetAction () \u003d\u003d MotionEvent. ACTION_DOWN) (ClipData clipData \u003d ClipData. NewPlainText ("", ""); View. DragShadowBuilder dsb \u003d new View. DragShadowBuilder (view); view. startDrag (clipData, dsb, view, 0); view. setVisibility (View. INVISIBLE); return true;) else (return false;))

Everything is very simple. So, we figured out the substitution of the image, let's move on to the next task.

Limiting the drag area for the drag drop function

There is one problem with limiting the drag area. The point is, if you drop the shape outside the board, the drop event will not happen, because the user dropped the object from scratch and the object has nothing to interact with. As a result, the figure will not return to its original state and will remain hidden forever. I spent a lot of time reading the documentation, but I still haven't found a way to limit the dragging area of \u200b\u200bobjects. The inspiration came suddenly. I don't need to constrain the area at all, I need to know if the user has released the shape correctly or not.

Determining the correct release
I found the answers to my questions in the "handling drag end events" section of the Android Developers site. Here are a few key points:

  1. When the user finishes dragging, the ACTION_DRAG_ENDED event is raised in the DragListeners handler.
  2. In the DragListener, you can get more detailed information about the drag operation by calling the DragEvent.getResult () method.
  3. If the DragListener returns true in response to the ACTION_DROP event, the getResult call will also return true, otherwise, false.

Thus, I need to intercept the ACTION_DRAG_ENDED event and call the getResult method. If it returns false, then the user has dragged the shape out of the board and I need to put the ImageView in visible mode.

@ Override public boolean onDrag (View view, DragEvent dragEvent) (int dragAction \u003d dragEvent. GetAction (); View dragView \u003d (View) dragEvent. GetLocalState (); if (dragAction \u003d\u003d DragEvent. ACTION_DRAG_EXITED) (containsDragable \u003d false;) else if (dragAction \u003d\u003d DragEvent. ACTION_DRAG_ENTERED) (containsDragable \u003d true;) else if (dragAction \u003d\u003d DragEvent. ACTION_DRAG_ENDED) (if (dropEventNotHandled (dragEvent)) (dragView. setVisibility (View. VISIBLE);)) else if (dragAction \u003d \u003d DragEvent. ACTION_DROP & amp; & amp; containsDragable) (checkForValidMove ((ChessBoardSquareLayoutView) view, dragView); dragView. SetVisibility (View. VISIBLE);) return true;) private boolean dropEventNotHandled (DragEvent dragEvent) (return! DragRult );)

Now the user can release the figure anywhere, and nothing bad will happen.

Determining Allowable Moves

The last part of the article is devoted to checking the validity of the move that the user is trying to make. Before starting to discuss this topic in detail, I will make a small remark explaining the structure of my application. The chessboard is represented as a TableLayout, and each cell is a descendant of a LinearLayout and has an OnDragListener.

In addition, each OnDragListener refers to a mediator object that takes care of the interaction of game objects and remembers the position of the current cell.

When the user drags a piece over a cage, the following actions are possible:

  1. Using the ACTION_DRAG_ENTERED event to set the ‘containsDraggable’ variable to true.
  2. Using the ACTION_DRAG_EXITED event to set the ‘containsDraggable’ variable to false.
  3. Using the ACTION_DROP event to ask the broker whether it is allowed to place a figure in this cell.

Below is the code that implements the described logic

@ Override public boolean onDrag (View view, DragEvent dragEvent) (int dragAction \u003d dragEvent. GetAction (); View dragView \u003d (View) dragEvent. GetLocalState (); if (dragAction \u003d\u003d DragEvent. ACTION_DRAG_EXITED) (containsDragable \u003d false;) else if (dragAction \u003d\u003d DragEvent. ACTION_DRAG_ENTERED) (containsDragable \u003d true;) else if (dragAction \u003d\u003d DragEvent. ACTION_DRAG_ENDED) (if (dropEventNotHandled (dragEvent)) (dragView. setVisibility (View. VISIBLE);)) else if (dragAction \u003d \u003d DragEvent. ACTION_DROP & amp; & amp; containsDragable) (checkForValidMove ((ChessBoardSquareLayoutView) view, dragView); dragView. SetVisibility (View. VISIBLE);) return true;)

As you can see, regardless of whether the move is legal or not, the ImageView is set to a visible state. I wanted the user to see the shape move. I mentioned earlier that the cell is a descendant of LayoutView. This is done to make it easier to move the ImageView from cell to cell. Below is the code for the checkForValidMove method that shows how the ImageView moves.

private void checkForValidMove (ChessBoardSquareLayoutView view, View dragView) (if (mediator. isValidMove (view)) (ViewGroup owner \u003d (ViewGroup) dragView. getParent (); owner. removeView (dragView); view. addView (dragView); view. setGravity (Gravity. CENTER); view. ShowAsLanded (); mediator. HandleMove (view);))

I hope this article will help you in developing your own projects.

182

In this example we select the div element and make it floatable by calling draggable () method... As shown in the figure below, in the opened document the element takes its normal position, but after that it can be moved using the mouse pointer to any place in the browser window:

The drag-and-drop feature is useful on its own, but it is even more useful when used in conjunction with the Droppable interaction described below.

Draggable's interaction is implemented solely through the use of specific HTML markup and CSS styles. This means that this functionality will work in almost any browser, but the elements endowed with it will not be able to work with similar native drag-and-drop tools of operating systems.

Drag-and-drop operations defined by the HTML5 specification are usually implemented using the native mechanisms of operating systems. If you are using jQuery UI's Drag-and-drop mechanism, it is best to disable the equivalent HTML5 features to avoid conflicts. To this end, set the draggable attribute of the document's body element to false.

Draggable interaction setup

There are many customization options for Draggable interaction. The most important properties, which are discussed in the following sections, are shown in the table below:

Draggable Interaction Properties
Property Description
axis Limits movement to specific directions. The default is false, meaning no constraints, but you can also specify "x" (move along the X axis only) or "y" (move along the Y axis only)
containment Constrains the position of the moved element to a specific area of \u200b\u200bthe screen. The types of supported values \u200b\u200bare described in the table below, using the corresponding example. The default is false, which means no restrictions
delay Determines how long an element must be dragged before it moves. The default is 0, which means no delay
distance Determines the distance that the user must drag an element from its starting position before it actually moves. The default is 1 pixel
grid Forces an item to be moved to grid cells. The default is false, which means no binding

Limiting directions of movement

There are several ways in which you can restrict the movement of an element to certain directions. The first is to use the axis option to constrain the direction of movement to the X or Y axis. An example is shown below:

...

Drag vertically
Drag horizontally
Run example

In this example, we define two div elements, select them with jQuery, and call the draggable () method. An object is passed to this method as an argument, which initially constrains the movement of both divs along the X-axis.Then applying the jQuery filter () method, we are able to select the dragV element without re-searching the entire document using jQuery and set it to another allowed direction of movement - along the Y-axis. This gives us a document in which one div can only be dragged vertically and the other only horizontally. The result is shown in the figure:

Limiting the range of movement of an element

You can also limit the area of \u200b\u200bthe screen where you can drag an item. The containment option is used for this. The value formats that can be specified in this option are described in the table below:

An example of using the containment option is shown below:

...

Drag horizontally
Drag inside parent
Run example

In this example, the movement of both elements is limited so that they can only be dragged within the parent element, which is a fixed-sized div. One of the divs being floated using the axis option has an additional restriction that it can only move horizontally within its parent. The result is illustrated in the figure:

Limiting the ability to move an item to grid cells

The grid option allows you to set the anchoring of the moved item to the grid cells. This option takes as a value an array of two elements that define the width and height of the grid cells in pixels. An example of using the grid option is shown below:

...

Drag me
Run example

This example has a grid with cells 100 pixels wide by 50 pixels high. When you drag an item, it "jumps" from one (invisible) cell to another. The snapping effect is a very good example of the use of interaction functionality, but it is difficult to convey it using screenshots.

You can create a snapping effect for only one direction by setting the free-move axis to 1. For example, if you set the grid option to a value, the item will snap to 100-pixel grid cells as it moves horizontally, but the vertical movement is free.

Move delay

There are two options that allow you to delay when dragging the item being moved. The delay option can be used to set the time, in milliseconds, that the user must drag the mouse pointer before the element is actually moved. Another kind of delay is provided by the distance option, which determines the distance, in pixels, that the user must drag the mouse pointer before an element follows.

An example of using both settings is shown below:

...

Time delay block
Block with minimum distance
Run example

In this example, there are two floating elements, one of which has a delay specified using the delay option and the other using the distance option.

In the case of a delay specified by the delay option, the user must drag for a specified amount of time before actually moving the element. In this example, the duration of this interval is 1000 ms. It is not at all necessary to move the mouse at this time, but during the entire delay period the mouse button must remain pressed, after which the element can be moved by moving the mouse. When the dwell time expires, the item being moved will snap to the position of the mouse pointer, subject to the constraints imposed by the grid, region, and axis options discussed earlier.

The distance option has a similar effect, but in this case the user must drag the mouse pointer at least the specified number of pixels in any direction from the element's starting location. Then the item being moved will jump to the current location of the pointer.

If you apply both settings to the same element, then the moved element will not budge until both delay criteria are met, i.e. until an attempt to drag the element lasts for the specified time and until the mouse pointer moves the specified number of pixels.

Using Draggable Interaction Methods

All of the methods defined for Draggable's interactions are part of the basic set of methods that you already saw when looking at widgets. Methods specific to Draggable interaction are not provided, so we will not cover them in detail. The list of available methods is shown in the table below:

Using Draggable Interaction Events

Draggable Interaction supports a simple set of events to notify when an item is dragged. These events are described in the table below:

As with widget events, you can also react to these events. An example of handling start and stop events is shown below:

...

Drag me
Run example

This example uses the start and stop events to change the text content of an element as it is being dragged. This opportunity is due to the fact that Draggable interaction is implemented exclusively using HTML and CSS: you can use jQuery to change the state of a floated element even while it is moving across the screen.

Using Droppable Interaction

In some situations, the ability to drag and drop an element alone may be sufficient, but it is most useful when used in conjunction with the Droppable interaction.

Elements that have had a Droppable interaction applied (receiving elements) acquire the ability to accept floating elements created by the Draggable interaction.

Receiving items are created using droppable () methodbut to get useful functionality you will need to create event handlers from among those defined for this type of interaction. The available events are shown in the table below:

Droppable interaction events
Event Description
create Occurs when a Droppable interaction is applied to an element
activate Occurs when the user starts dragging a floated item
deactivate Occurs when the user stops dragging a floated item
over Occurs when the user drags a floated element over the receiving element (but assuming the mouse has not been released yet)
out Occurs when the user drags the floated element outside of the receiving element
drop Occurs when the user leaves the float on the receiving element

An example of creating a simple receiving element with a single drop event handler is shown below:

...

Leave here
Drag me
Run example

In this example, a div element has been added to the document with the text content represented by the line "Leave here". We select this element using jQuery and call the droppable () method, passing it a settings object that defines a handler for the drop event. The response to this event is to change the text of the floated element using the text () method.

The drag-and-drop interactive interaction created in this example is very basic, but it provides a convenient context for explaining how Draggable and Droppable interactions can work together. The various stages of the drag-and-drop process are illustrated in the figure:

It all looks very simple. We drag the floated element until it is over the receiving element and release it. The item being moved remains where it was dropped, and its text content changes in response to a drop event. The following sections demonstrate how to use other Droppable interaction events to improve the user experience.

Highlighting the target receiving object

Using the activate and deactivate events, you can highlight the target receiving object when the user begins the dragging process. In many situations, this idea is very fruitful, as it gives the user a reliable indication of which elements are part of the drag-and-drop model. A relevant example is given below:

... $ (function () ($ ("# draggable"). draggable (); $ ("# droppable"). droppable ((drop: function () ($ ("# draggable"). text ("Left ")), activate: function () ($ (" # droppable "). css ((border:" medium double green ", backgroundColor:" lightGreen "));), deactivate: function () ($ (" # droppable ") .css (" border "," ") .css (" background-color "," ");)));)); ... Run example

As soon as the user starts dragging an element, the activate event - associated with our receiving element - fires, and the handler function uses the css () method to change the element's border and background-color CSS properties. As a result, the target receiving element is highlighted, indicating to the user that there is a relationship between it and the floated element.

The deactivate event is used to remove CSS property values \u200b\u200bfrom the receiving element and reset it to its original state as soon as the user releases the mouse button. (This event occurs whenever the dragging of an element stops, whether the element being dragged is kept on the receiving element or not.) This process is illustrated in the figure:

Overlapping Elements

Drag-and-drop can be enhanced by adding over and out event handling. The over event occurs when 50% of the floated element is over any part of the receiving element. The out event occurs when previously overlapping elements no longer overlap. An example of the response to these events is shown below:

$ (function () ($ ("# draggable"). draggable (); $ ("# droppable"). droppable ((drop: function () ($ ("# draggable"). text ("Dropped")) , activate: function () ($ ("# droppable"). css ((border: "medium double green", backgroundColor: "lightGreen"));), deactivate: function () ($ ("# droppable"). css ("border", "") .css ("background-color", "");), over: function () ($ ("# droppable"). css ((border: "medium double red", backgroundColor : "red"));), out: function () ($ ("# droppable"). css ("border", "") .css ("background-color", "");)));) ); Run example

The same handler functions are used here as in the previous example, but in this case they are associated with the over and out events. When at least 50% of the floated element overlaps with the receiving element, it is framed and its background color changes, as shown:

The specified 50% limit is called the overlap threshold (tolerance), the value of which can be set when creating the receiving element, as shown below.

Droppable interaction setup

Droppable has a number of properties for interaction that can be changed to customize its behavior. These properties are listed in the table below:

Droppable interaction properties
Property Description
disabled If this option is true, then the Droppable interaction functionality is initially disabled. The default is false
accept Narrows down the set of floating elements that the receiving element will respond to. The default is *, it matches any element
activeClass Defines a class to be assigned in response to an activate event and removed in response to a deactivate event
hoverClass Defines a class that will be assigned in response to an over event and removed in response to an out event
tolerance Specifies the minimum degree of overlap at which the over event occurs

Restricting Allowed Movable Items

It is possible to restrict the set of floated elements that will be accepted by an element with Droppable interoperability using the accept option. The accept option should be set to a selector. As a result of this, Droppable interaction events will only occur if the item being dropped matches the specified selector. A relevant example is given below:

...

Leave here
Element 1
Element 2
Run example

In this example, there are two floatable elements named drag1 and drag2. When creating a receiving element, the accept option is used, with which we indicate that only drag1 is an acceptable float element.

As you drag drag1, you will see the same effect as in the previous examples. The activate, deactivate, over and out events will fire on the receiving element at appropriate times. At the same time, if you drag a drag2 element that does not match the selector specified in the accept parameter, these events will not be fired. This element can be freely moved, but it will not be perceived by the receiving element.

Notice the change in the way you select an acceptable float for which you should call text (). When there was only one moveable element in the document, the id attribute was enough for this:

Drop: function () ($ ("# draggable"). Text ("Left")),

In this example, there are two float elements, and selecting on the id attribute will not produce the desired result, since the text in this case will always change in the same float element, no matter which one is acceptable to the receiving element.

The way out is to use the ui object that jQuery UI provides as an additional argument to each event handler. The draggable property of the ui object returns a jQuery object containing the element that the user drags or tries to leave on the target element, allowing the desired element to be selected as follows:

Drop: function (event, ui) (ui.draggable.text ("Left")),

Changing the overlap threshold

By default, the over event only fires when at least 50% of the floated element overlaps with the receiving element. The value of this threshold overlap can be changed using the tolerance option, which can take on the values \u200b\u200bshown in the table below:

Most often, I use two values, fit and touch, because their meaning is most understandable for users. I use the fit value when the dragged element should remain in the area of \u200b\u200bthe receiving element to which it was moved, and the touch value when the moved element should return to its original position (an example will be given below). An example of using fit and touch parameters is shown below:

The clone value tells jQuery UI to create a copy of the floated element, along with all its content, and use that result as a helper element. The result is shown in the figure:

The helper is removed when the user releases the mouse button over the floated element, leaving the floated and receiving elements in their original positions.

As shown in the figure, the original floating element remains in place and only the auxiliary element moves along the screen following the mouse pointer. If the dimensions of the moved element are large, as in our example, then it covers the rest of the document elements, so that even the user will find it difficult to track the position of the receiving element. You can work around this problem by providing a function as the value for the helper option, as shown in the example below:

... $ (function () ($ ("div.draggable") .. png "/\u003e")))); $ ("# basket"). droppable ((activeClass: "active", hoverClass: "hover")); )); ... Run example

When the user starts dragging an element, jQuery UI calls the function specified by the helper parameter and uses the returned element as the float. In this case, I'm using jQuery to create an img element. The result is shown in the figure:

The small image acts as a placeholder for the floating element, making it much easier to keep track of other elements in the document.

The ui that jQuery UI dispatches to Droppable interaction events contains a helper property, and this property can be used to manipulate the helper as it is being dragged. An example of using this property in conjunction with the over and out events is shown below:

... $ (function () ($ ("div.draggable") .. png "/\u003e")))); $ ("# basket"). droppable ((activeClass: "active", hoverClass: "hover", over: function (event, ui) (ui.helper.css ("border", "thick solid # 27e6ed")) , out: function (event, ui) (ui.helper.css ("border", "")))); )); ...

Here, the over and out events and the ui.helper property are used to display a border around the helper when it overlaps the receiving element. The result is shown in the figure:

Snap to the edges of elements

Via snap options you can achieve that the moved element is "attracted" to the edges of the elements next to which it passes. This option takes a selector as a value. The floated element will snap to the edges of any element that matches the specified selector. An example of using the snap option is shown below:

Run example jQuery UI

Basket
Tie in here
Drag me

When the moved element approaches one of the suitable elements, it is, as it were, "attracted" to it in such a way that their adjacent edges touch. Any element can be selected for this binding, not just the receiving one. In this example, I've added a div element and set the snap option to a value that selects this element in the document, as well as the receiving element.

There are a couple of helper options that allow you to fine-tune the binding behavior of elements. One of them is snapMode option... It can be used to specify the type of binding. The following values \u200b\u200bare accepted: inner (snapping to the inner edges of elements), outer (snapping to the outside edges of elements) and both (snap to all edges; default).

SnapTolerance option allows you to specify how far the floated element should get close to the edge of the target element before snapping occurs. The default is 20, which means 20 pixels. The example uses a value of 50, which corresponds to a snapping at a greater distance. It is very important to choose the correct value for this option. If the snapTolerance option is too small, the user may not notice the snap effect, and if it is too large, the item being moved will start making unexpected jumps, snapping to far away items.