Jump to content
  • Advertisement
Sign in to follow this  
grumpyOldDude

Looking to fix drag and drop anomalies

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

If you intended to correct an error in the post then please contact us.

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.DragShadowBuilder;
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.
			View.DragShadowBuilder myShadow = new DragShadowBuilder(ima);
			 
			// Starts the drag
			v.startDrag(dragData, // the data to be dragged
				myShadow, // the drag shadow builder
				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 this post


Link to post
Share on other sites
Advertisement

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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!