Home » Android » java – Android beginner – Place Image at DragEvent

java – Android beginner – Place Image at DragEvent

Posted by: admin May 14, 2020 Leave a comment

Questions:

I realize that similar questions have been posted, and I’ve viewed them and lots of other topics etc to find a solution – I’m clearly missing the obvious – as I am still learning the basics!

Goal: Simple drag and drop.
User moves image across screen and either drops on top of another image or anywhere on the screen.

API: >11

Completed:

  • Can drag the image and place on top of another image and get response (using Toast to confirm).
  • Can drag the image anywhere on screen and get response (using Toast to confirm).

NOT working:

  • Cannot drag image anywhere on screen and deposit image where finger lifted

I have tried lots of different methods but always compiling errors. Looking at my code, could anyone recommend a clean and simple method to place a image at ACTION_DRAG_ENDED (keep in mind I am a beginner)

Here is my java code:

public class MainActivity extends Activity {
@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.activity_main, menu);
    return true;
}

boolean okToDrop;

/** Called when the activity is first created. */
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    findViewById(R.id.oval).setOnTouchListener(new theTouchListener());
    findViewById(R.id.square).setOnTouchListener(new theTouchListener());
    findViewById(R.id.robot).setOnTouchListener(new theTouchListener());
    findViewById(R.id.oval).setOnDragListener(new theDragListener());
    findViewById(R.id.square).setOnDragListener(new theDragListener());
    findViewById(R.id.robot).setOnDragListener(new theDragListener());
}

private final class theTouchListener implements OnTouchListener {
    public boolean onTouch(View view, MotionEvent motionEvent) {
        if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
            ClipData data = ClipData.newPlainText("", "");
            DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(
                    view);
            view.startDrag(data, shadowBuilder, view, 0);
            view.setVisibility(View.VISIBLE);
            return true;
        } else {
            return false;
        }
    }
}

class theDragListener implements OnDragListener {
    @Override
    public boolean onDrag(View view, DragEvent dragEvent) {
        int dragAction = dragEvent.getAction();
        View dragView = (View) dragEvent.getLocalState();
        if (dragAction == DragEvent.ACTION_DRAG_EXITED) {
            okToDrop = false;
        } else if (dragAction == DragEvent.ACTION_DRAG_ENTERED) {
            okToDrop = true;
        } else if (dragAction == DragEvent.ACTION_DRAG_ENDED) {
            if (dropEventNotHandled(dragEvent) == true) {

                // Code to generate image goes here ***********************

                Context context = getApplicationContext();
                CharSequence text = "Action Dropped Not In Box!";
                int duration = Toast.LENGTH_SHORT;
                Toast toast = Toast.makeText(context, text, duration);
                toast.show();

                dragView.setVisibility(View.VISIBLE);
            }
        } else if (dragAction == DragEvent.ACTION_DROP && okToDrop) {
            ImageView i = (ImageView) findViewById(R.id.square);
            i.setImageResource(R.drawable.oval);

            dragView.setVisibility(View.INVISIBLE);

            Context context = getApplicationContext();
            CharSequence text = "Action Resulted In It Being Dropped In The Box";
            int duration = Toast.LENGTH_SHORT;
            Toast toast = Toast.makeText(context, text, duration);
            toast.show();

        }
        return true;
    }

    private boolean dropEventNotHandled(DragEvent dragEvent) {
        return !dragEvent.getResult();
    }

}

And my xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity" >

    <ImageView
        android:id="@+id/square"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_centerVertical="true"
        android:src="@drawable/square_box" />

    <ImageView
        android:id="@+id/oval"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:layout_marginLeft="58dp"
        android:layout_marginTop="58dp"
        android:src="@drawable/oval" />

    <ImageView
        android:id="@+id/robot"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/oval"
        android:layout_below="@+id/square"
        android:layout_marginTop="70dp"
        android:src="@drawable/ic_launcher" />

</RelativeLayout>
How to&Answers:

Although I am not sure if my implementation is the best way to go by, it works.

Add these members in your MainActivity:

View root; // references root activity view
float dropX, dropY; // records position of where finger was lifted on the root

In your onCreate():

root = findViewById(android.R.id.content); // get reference to root
// add a Draglistener to your root view
root.setOnDragListener(new OnDragListener() {
    @Override
    public boolean onDrag(View v, DragEvent event) {
        int action = event.getAction();
        if(action == DragEvent.ACTION_DROP) {
            // record position of finger lift
            dropX = event.getX();
            dropY = event.getY();
        }
        return false;
    }
});

Finally, place these lines under // Code to generate image goes here:

dragView.setX(dropX - dragView.getWidth() / 2);
dragView.setY(dropY - dragView.getHeight() / 2);

Hope this helps.

Answer:

OK! So your problem is not using the same drag listener.

findViewById(R.id.oval).setOnDragListener(new theDragListener());

should be

theDragListener draglistener = new theDragListener();
findViewById(R.id.oval).setOnDragListener(draglistener);