• 9
• 9
• 9
• 10
• 10

# Looking to fix drag and drop anomalies

This topic is 451 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Still in the process of understanding Android system...

Drag N Drop which would be a key part of my game is an issue at the moment

Right now when I run the code below I can 'drag' an image-view (clown face) only down-right or down. So this means I can never drag back up or left-up direction.

And also its movement resolution is very poor (way too large) - which means it skips big gaps... I can't drag to very small/short step. I can't even control this step resolution (nor the direction)

These constraints are not good at all, I would like to have complete freedom of direction of movement and allow for short steps for this drag and drop. But understanding this code is mysteriously strange, when I try to change the part of the code I thought should fix the above constraints, it either goes worse, caused a crash or has no effect at all

I'm hoping someone more knowledgeable with Android than I could help solve this , many  thnx

[attachment=34649:my clown fce2.jpg]

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >

<ImageView
android:id="@+id/iv_logo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/thumb"
android:contentDescription="Click to drag and drop" />

</RelativeLayout>


=====================================================================================================

import android.os.Bundle;
import android.app.Activity;
import android.content.ClipData;
import android.content.ClipDescription;
import android.util.Log;
import android.view.DragEvent;
import android.view.View;
import android.view.View.OnDragListener;
import android.widget.*;

public class MainActivity5 extends Activity{
ImageView ima;
private static final String IMAGEVIEW_TAG = "Android Logo";
String msg;

private android.widget.RelativeLayout.LayoutParams layoutParams;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity5);

ima = (ImageView)findViewById(R.id.iv_logo);
ima.setTag(IMAGEVIEW_TAG);

ima.setOnLongClickListener(new View.OnLongClickListener() {
@SuppressWarnings("deprecation")
@Override
public boolean onLongClick(View v) {
ClipData.Item item = new ClipData.Item((CharSequence)v.getTag());

String[] mimeTypes = {ClipDescription.MIMETYPE_TEXT_PLAIN};
ClipData dragData = new ClipData( v.getTag().toString(), mimeTypes, item );

// Instantiates the drag shadow builder.

// Starts the drag
v.startDrag(dragData, // the data to be dragged
null, // no need to use local data
0 // flags (not currently used, set to 0)
);
return true;
}});

// Create and set the drag event listener for the View
ima.setOnDragListener( new OnDragListener(){
@Override
public boolean onDrag(View v, DragEvent event){
switch(event.getAction()){
case DragEvent.ACTION_DRAG_STARTED:
layoutParams = (RelativeLayout.LayoutParams)
v.getLayoutParams();
Log.d(msg, "Action is DragEvent.ACTION_DRAG_STARTED");
// Do nothing
break;
case DragEvent.ACTION_DRAG_ENTERED:
Log.d(msg, "Action is DragEvent.ACTION_DRAG_ENTERED");
int x_cord = (int) event.getX();
int y_cord = (int) event.getY();
break;
case DragEvent.ACTION_DRAG_EXITED :
Log.d(msg, "Action is DragEvent.ACTION_DRAG_EXITED");
x_cord = (int) event.getX();
y_cord = (int) event.getY();
layoutParams.leftMargin = x_cord;
layoutParams.topMargin = y_cord;
v.setLayoutParams(layoutParams);
break;
case DragEvent.ACTION_DRAG_LOCATION :
Log.d(msg, "Action is DragEvent.ACTION_DRAG_LOCATION");
x_cord = (int) event.getX();
y_cord = (int) event.getY();
break;
case DragEvent.ACTION_DRAG_ENDED :
Log.d(msg, "Action is DragEvent.ACTION_DRAG_ENDED");
// Do nothing
break;
case DragEvent.ACTION_DROP:
Log.d(msg, "ACTION_DROP event");
// Do nothing
break;
default: break;
}
return true;
}
});
}
}



##### Share on other sites

Have you tried to use the debug to map the coords of the movement?

##### Share on other sites

The debugger hasn't helped in this case

Its a matter of understanding the code/Android system and tweaking the logics to make it work

At a glance it seems deceptively simple, but nothing that I've done has worked so far  :( ......  HELP!!!!

##### Share on other sites
I'm not deeply familiar with Android so I couldn't confirm this at a glance, so maybe you can shed some light:

You need to handle drag events when the image is overlapping itself, as well as drag events generated when the image is moving over its background or container.

A cursory reading of your code suggested to me that maybe this isn't happening as it should. I'd start with that.

##### Share on other sites

I'm not deeply familiar with Android so I couldn't confirm this at a glance, so maybe you can shed some light:

You need to handle drag events when the image is overlapping itself, as well as drag events generated when the image is moving over its background or container.

A cursory reading of your code suggested to me that maybe this isn't happening as it should. I'd start with that.

Yeah, but the problem is not the picking (drag event)  or "DragShadowBuilder". The main problem is that the drag movement cannot be reversed in direction.

So it only moves down, right or down-right directions.   It doesn't allow to get dragged up, left or up-left directions

I guess it mostly has to do with this code

case DragEvent.ACTION_DRAG_LOCATION :
Log.d(msg, "Action is DragEvent.ACTION_DRAG_LOCATION");
x_cord = (int) event.getX();
y_cord = (int) event.getY();
break;


But the thing I don't how to tweak it to make "draggable in all directions

##### Share on other sites
On most platforms I've worked with, drag and drop is implemented as three phases:

- Initiate (click + hold)
- Drag (hold + move)
- Drop (release button/finger)

Drag events are typically generated when the dragged object moves over top of something else.

There are two things in your program that might generate a drag event:

- The image itself
- The background/container

You appear to be handling only one of those two, unless you can point me to the specific code that handles both.

Your description of the problem is consistent with only handling drag events on the image but not the background. My Java is shitty (because Java is shitty, but that's another thread) but it looks like you only attach drag event handling code to the image, not the background.

##### Share on other sites

Sorry, I was busy editing my previous reply so I didn't see yours in time

On the principle you must be correct

Since you are not familiar with Android, then can you describe in psuedocode how to handle the drag event on the background, then I will try and work it out to Android from there

Many thanks

##### Share on other sites
My guess would be in your ACTION_DRAG_ENTERED case and the possibility that your variables x_coord and y_coord in that block are declared local scope instead of the x_coord and y_coord you use in the other cases assumed declared globally somewhere not shown.

Again, just a guess.
Would make some sense if events had a relative to relationship.

Edit: whoops apologies for butting in. I don't know java at all.

##### Share on other sites

My guess would be in your ACTION_DRAG_ENTERED case and the possibility that your variables x_coord and y_coord in that block are declared local scope instead of the x_coord and y_coord you use in the other cases assumed declared globally somewhere not shown.

Again, just a guess.
Would make some sense if events had a relative to relationship.

Edit: whoops apologies for butting in. I don't know java at all.

I thought of this myself,  but when I declared x_cord and y_cord globally, I got the following syntax error

Cannot refer to the non-final local variable x_cord defined in an enclosing scope
Cannot refer to the non-final local variable y_cord defined in an enclosing scope

But when I changed the globally declared variable to final , i got this error

The final local variable x_cord cannot be assigned, since it is defined in an enclosing type


so i had to revert back to original state

##### Share on other sites
It shouldn't be complicated. Just use the setOnDragListener() or analogous function on the container that holds your image.

Frankly that should be well within your reach to figure out at this point.