Looking to fix drag and drop anomalies

Started by
12 comments, last by Helo7777 7 years, 2 months ago

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;
			}
		});
	}
}

can't help being grumpy...

Just need to let some steam out, so my head doesn't explode...

Advertisement

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

Developer with a bit of Kickstarter and business experience.

YouTube Channel: Hostile Viking Studio
Twitter: @Precursors_Dawn

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!!!!

can't help being grumpy...

Just need to let some steam out, so my head doesn't explode...

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.

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

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

can't help being grumpy...

Just need to let some steam out, so my head doesn't explode...

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.

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

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

can't help being grumpy...

Just need to let some steam out, so my head doesn't explode...

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.

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

can't help being grumpy...

Just need to let some steam out, so my head doesn't explode...

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.

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

This topic is closed to new replies.

Advertisement