ACTION_DRAG_STARTED gets called on all views - android

In my code I have a LinearLayout that has child views, along with creating every child view (via code not xml) I set setOnLongClickListener and setOnDragListener, and it works with a horrible down side effect, that when onDrag gets called on one of the child views, case DragEvent.ACTION_DRAG_STARTED: gets called on all of the child views. why is that?
childView.setOnDragListener(new View.OnDragListener() {
#Override
public boolean onDrag(final View aChildView, DragEvent event) {
switch (event.getAction()) {
case DragEvent.ACTION_DRAG_STARTED:
Log.d("++++", "Drag Started");
aChildView.addView(Early Made up view);
break;
case DragEvent.ACTION_DRAG_ENTERED:
break;
case DragEvent.ACTION_DRAG_EXITED:
childView.setBackground(new ColorDrawable(Color.TRANSPARENT));
break;
case DragEvent.ACTION_DROP:
childView.setBackground(new ColorDrawable(Color.TRANSPARENT));// In case it got dropped on itself.
break;
case DragEvent.ACTION_DRAG_ENDED:
break;
default:
return false;
}
return true;
}
});
The thing is, that the early made up view appears inside all the child views not just the one that is being dragged.

I believe the answer to my question is that Action Drag Started fired for all views that supports drag and drop in the layout, while Action Drop is for the view that received the drop.
https://stackoverflow.com/a/13301939/5851265

Related

How to set Action in DragEvent

I am using OnDragListener to drag and drop image. i have MOTIONEVENT.ACTION_MOVE to implement image moving functionality. At a certain point in the action move, I want to end the drag and remove its shadow. Is it possible to set the action in drag event? Before releasing finger i want to call drop event.
switch(event.getAction()) {
case MotionEvent.ACTION_MOVE:
//here i want to remove shadow and stop dragging
break;
case DragEvent.ACTION_DROP:break;
}
You can implement OnDragListener in your class/ fragments.
class MyDrag implements OnDragListener {
Drawable image = getResources().getDrawable(
R.drawable.shape_droptarget);
#Override
public boolean onDrag(View v, DragEvent event) {
int action = event.getAction();
switch (event.getAction()) {
case DragEvent.ACTION_DRAG_STARTED:
// Signals the start of a drag and drop operation
break;
case DragEvent.ACTION_DRAG_ENTERED:
//Signals to a View that the drag point has entered the bounding box of the View
v.setBackgroundDrawable(image);
break;
case DragEvent.ACTION_DRAG_EXITED:
//Signals that the user has moved the drag shadow out of the bounding box of the View or into a descendant view that can accept the data.
v.setBackgroundDrawable(image);
break;
case DragEvent.ACTION_DROP:
// Signals to a View that the user has released the drag shadow, and the drag point is within the bounding box of the View and not within a descendant view that can accept the data.
View view = (View) event.getLocalState();
ViewGroup owner = (ViewGroup) view.getParent();
owner.removeView(view);
LinearLayout container = (LinearLayout) v;
container.addView(view);
view.setVisibility(View.VISIBLE);
break;
case DragEvent.ACTION_DRAG_ENDED:
//Signals to a View that the drag and drop operation has concluded.
v.setBackgroundDrawable(image);
default:
break;
}
return true;
}
}
for more details refer here Drag and Drop

Android, how to know specific target of DragListener

Hi everyone i'm trying to implement a drag and drop custom system and i'm struggling at the very last part. On my method:
#Override
public boolean onDrag(View v, DragEvent event) {
switch (event.getAction()) {
case DragEvent.ACTION_DRAG_STARTED: break;
case DragEvent.ACTION_DRAG_ENTERED: break;
case DragEvent.ACTION_DRAG_EXITED: break;
case DragEvent.ACTION_DROP:
View dragged = (View) event.getLocalState();
Log.e("DROPPED", "?");
Log.e("DRAGGED VIEW = " + dragged.toString(), "?");
Log.e("TARGET = " + getResources().getResourceName(v.getId()), "?");
break;
case DragEvent.ACTION_DRAG_ENDED: break;
default: break;
}
return true;
}
This works pretty fine, my problem is that as a target i get the parent root view instead of the specific layout where i want to place the draggable.
How can i achieve that my target is recognized where the drop ended? Do i have to compare X and Y coords or there is another more practical method?
I want to point out that mi parent root view has like 2 layouts inside, but wherever i end the drop event always get's the parent ID as a result, not the child ones.
Okey in case someone is as stu... as i am. The problem was that i defined the setOnDragListener in the parent layout instead of the child where i wanted the draggable items to be placed.

Android drag and drop on another view

I'm making Android application and I want this feature:
User can drag some view and when he dropt on some another view, I can register that he dropt on some view and do some work with that view.
For example:
There are two ImageView, one blue one red, and there is thrid ImageView, when user dropt third ImageView on blue one I have to call method1() and otherwise when user dropt on red one I have to call method2().
I have implemented standrad drag listener:
imageView.setOnDragListener(new View.OnDragListener() {
#Override
public boolean onDrag(View v, DragEvent event) {
switch(event.getAction())
{
case DragEvent.ACTION_DRAG_STARTED:
Log.e(msg, "Action is DragEvent.ACTION_DRAG_STARTED");
return true;
case DragEvent.ACTION_DRAG_ENTERED:
Log.e(msg, "Action is DragEvent.ACTION_DRAG_ENTERED");
return true;
case DragEvent.ACTION_DRAG_EXITED :
Log.e(msg, "Action is DragEvent.ACTION_DRAG_EXITED");
break;
case DragEvent.ACTION_DRAG_LOCATION :
Log.e(msg, "Action is DragEvent.ACTION_DRAG_LOCATION");
break;
case DragEvent.ACTION_DRAG_ENDED :
Log.e(msg, "Action is DragEvent.ACTION_DRAG_ENDED");
break;
case DragEvent.ACTION_DROP:
Log.e(msg, "ACTION_DROP event");
break;
default: break;
}
return true;
}
});
You don't need to calculate rects. You should call setOnDragListener two times, once on the red image view to handle the drop events on it, and once on the blue image view to handle drop events on it. Also just in case, I don't see the code where you need to call startDrag on the view that user is dragging during the touch event to start the drag.
So, you need to call view.startDrag in order to listen to the callbacks.
You can move your view in ACTION_MOVE, and check the intersection in ACTION_DROP.
This can also be directly achieved by OnTouchListener.
You can get the full example here.

ACTION_DRAG_STARTED in draglistener is never called for first time android

I am having two Draglisteners
Listener A it is placeholder to drop a particular item into it.(LinearLayout)
Listener B the item which is being drop.(its a relative layout)
When i drag the relative layout it is drawing the shadow but when dropped resulting false.
I set the visiblity View.VISIBLE of LinearLayout only when the relative layout is being dragged.
The draglistener code for linearlayout
#Override
public boolean onDrag(View v, DragEvent dragevent) {
switch (dragevent.getAction()) {
case DragEvent.ACTION_DRAG_STARTED:
break;
case DragEvent.ACTION_DRAG_ENTERED:
// setting background
break;
case DragEvent.ACTION_DRAG_EXITED:
break;
case DragEvent.ACTION_DROP:
// updating my view
break;
case DragEvent.ACTION_DRAG_ENDED:
break;
default:
break;
}
return true;
}
But only for the first time the DROP result is false from the second time it is working correct. And I set the draglistener when the activity created. Can anyone help me in this.

ListView onItemClickListener never triggered

I created a custom view which overrides onTouchListener in order to have differents images drown depending on the action performed by the user. (To change the background of the view when the user click on it for example).
I want to use this custom view in a ListView, so I created a custom adapter which displays all my views but the onItemClickListener of my ListView is never triggered.
What can I do ?
Here's the code from my Custom View:
#Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
setMode(MODE_SELECTED);
invalidate();
break;
case MotionEvent.ACTION_UP:
setMode(MODE_NONE);
invalidate();
break;
case MotionEvent.ACTION_CANCEL:
setMode(MODE_NONE);
invalidate();
break;
case MotionEvent.ACTION_OUTSIDE:
setMode(MODE_NONE);
invalidate();
break;
default:
break;
}
return true;
}
Ok, I found a solution : I use StateListDrawable and it avoids me to override the onTouch of my custom view !

Categories

Resources