user3213793
user3213793

Reputation: 11

OnDrag cannot receive DragEvent.ACTION_DROP

I have faced a problem following: I want to implement View.DragOnListener for a LinearLayout. When i long Click on the screen, OnDrag method received DragEvent.ACTION_DRAG_STARTED, but when i release drag on the screen. This method cannot received DragEvent.ACTION_DROP. Hope to get some helps from everyone. Here my code:

package com.example.dragdroptestapp;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.DragEvent;
import android.view.View;
import android.widget.LinearLayout;

public class MyLinearLayout extends LinearLayout implements View.OnDragListener{

    private final String TAG = "MyLinearLayout";
    public MyLinearLayout(Context context) {
        super(context);
        initLongClick();

    }


    public MyLinearLayout(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        initLongClick();
    }


    public MyLinearLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        initLongClick();
    }

    @Override
    public boolean onDragEvent(DragEvent event) {
        final int action = event.getAction();
        switch (action) {
        case DragEvent.ACTION_DRAG_STARTED:
            Log.e(TAG, "Started");
            break;
        case DragEvent.ACTION_DRAG_ENTERED:
            Log.e(TAG, "Entered");
            break;
        case DragEvent.ACTION_DROP:
            Log.e(TAG, "Droped");
            break;
        default:
            Log.e(TAG, "action event" + String.valueOf(action));
            break;
        }
        return true;
    }

    @Override
    public boolean onDrag(View v, DragEvent event) {
        Log.e(TAG, "onDrag");
        final int action = event.getAction();
        switch (action) {
        case DragEvent.ACTION_DRAG_STARTED:
            Log.e(TAG, "Started");
            break;
        case DragEvent.ACTION_DRAG_ENTERED:
            Log.e(TAG, "Entered");
            break;
        case DragEvent.ACTION_DROP:
            Log.e(TAG, "Droped");
            break;      
        default:
            break;
        }
        return true;
    }
    private void initLongClick() {
        setOnLongClickListener(new OnLongClickListener() {

            @Override
            public boolean onLongClick(View v) {

                Log.e(TAG, "LongClick");
                View.DragShadowBuilder myShadow = new DragShadowBuilder(v);
                v.startDrag(null, myShadow, null, 0);

                return true;
            }
        });
    }


}

Upvotes: 1

Views: 2846

Answers (4)

aliraza12636
aliraza12636

Reputation: 473

It is because may be you are trying to drop the view in some other view which is not the parent of that dragging view or may be the parent of the dragging view is inside some other view so the listening of drop event is not coming to the actual parent but the root of that parent (and the root is not registered with the DragListner )

Upvotes: 0

lalit sonawane
lalit sonawane

Reputation: 62

Below code might help others who are struggling with similar issue.

package com.javapapers.android.drag_drop; 
import android.os.Bundle; import android.app.Activity; 
import android.view.*; 
import android.view.View.OnDragListener; 
import android.view.View.OnTouchListener; 
import android.view.View.DragShadowBuilder; 
import android.widget.LinearLayout; 
import android.util.Log; 
import com.javapapers.android.drag_drop.R; 

public class MainActivity extends Activity implements OnTouchListener, OnDragListener {
    private static final String LOGCAT = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        findViewById(R.id.textView1).setOnTouchListener(this);
        findViewById(R.id.pinkLayout).setOnDragListener(this);
        findViewById(R.id.yellowLayout).setOnDragListener(this);
    }

    public boolean onTouch(View view, MotionEvent motionEvent) {
        if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
            DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(view);
            view.startDrag(null, shadowBuilder, view, 0);
            view.setVisibility(View.INVISIBLE);
            return true;
        }
        else {
            return false;
        }   
    }

    public boolean onDrag(View layoutview, DragEvent dragevent) {
        int action = dragevent.getAction();      
        switch (action) {    
            case DragEvent.ACTION_DRAG_STARTED:
            Log.d(LOGCAT, "Drag event started");
            break;

            case DragEvent.ACTION_DRAG_ENTERED:
            Log.d(LOGCAT, "Drag event entered into " + layoutview.toString());
            break;

            case DragEvent.ACTION_DRAG_EXITED:
            Log.d(LOGCAT, "Drag event exited from "+layoutview.toString());
            break; 

            case DragEvent.ACTION_DROP:
            Log.d(LOGCAT, "Dropped");
            View view = (View) dragevent.getLocalState();
            ViewGroup owner = (ViewGroup) view.getParent();
            owner.removeView(view);
            LinearLayout container = (LinearLayout) layoutview;
            container.addView(view);
            view.setVisibility(View.VISIBLE);
            break;

            case DragEvent.ACTION_DRAG_ENDED:
            Log.d(LOGCAT, "Drag ended");
            break;

            default:
            break;   
        }
    return true;
}

Upvotes: 0

Bob Liberatore
Bob Liberatore

Reputation: 896

I just got done wrestling with a similar issue. The View that was mysteriously receiving ACTION_DRAG_STARTED and ACTION_DRAG_ENDED but not ACTION_DROP was underneath another much larger view that was also listening for drag events (but would only do anything with them if they were dropped in specific areas).

I fixed this by moving the larger towards the top of the XML layout file, which put it "underneath" the smaller View.

Upvotes: 2

JNI_OnLoad
JNI_OnLoad

Reputation: 5442

I also had same issue, ACTION_DROP is not received usually due to following reasons: 1. OnDragListner should be applied on the layout rather then on view 2. You should return true instead break; from ACTION_DRAG_STARTED as if it would not be true it will continue to next ACTION. so return true from each ACTION.

So it is bit tough to tell on what you are setting OnDrag either layout or view, if you are calling on view then change it for layout.

Next instead of breaking from each ACTION in OnDragEvent just return true. This should solve your problem.

I hope I helped

Upvotes: 1

Related Questions