Android drag and drop on another view - android

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.

Related

Android - multiple finger touches for 1 button

I want a button that can detect multiple fingers. Like ı am holding with 1 finger and then 1 more finger touches that button it has to detect that.
Or
a button that when pushed, automatically release that button dont care if it actually released or not.
I use onTouchevent for multiple buttons for my drum kit project.
#Override
public boolean onTouch(View view, MotionEvent motionEvent)
{
Animation zoomIn = AnimationUtils.loadAnimation(getApplicationContext(),R.anim.zoomin);
switch (motionEvent.getAction())
{
case MotionEvent.ACTION_DOWN:
switch(view.getId())
{
case R.id.BassL:
findViewById(R.id.bass).startAnimation(zoomIn);
sp.play(BassD,1.0f,1.0f,0,0,1.0f);
break;
case R.id.BassR:
findViewById(R.id.bass).startAnimation(zoomIn);
sp.play(BassD,1.0f,1.0f,0,0,1.0f);
break;
case R.id.SnareL:
findViewById(R.id.snare).startAnimation(zoomIn);
sp.play(SnareD,1.0f,1.0f,0,0,1.0f);
break;
case R.id.SnareR:
findViewById(R.id.snare).startAnimation(zoomIn);
sp.play(SnareD,1.0f,1.0f,0,0,1.0f);
break;
case R.id.OpenHihat:
findViewById(R.id.hihat).startAnimation(zoomIn);
sp.stop(OpenH);
sp.play(OpenH,1.0f,1.0f,0,0,1.0f);
break;
case R.id.CloseHihat:
findViewById(R.id.hihat).startAnimation(zoomIn);
sp.play(CloseH,1.0f,1.0f,0,0,1.0f);
break;
case R.id.RideSurface:
findViewById(R.id.ride).startAnimation(zoomIn);
sp.stop(RideS);
sp.play(RideS,1.0f,1.0f,0,0,1.0f);
break;
case R.id.RideTop:
findViewById(R.id.ride).startAnimation(zoomIn);
sp.play(RideT,1.0f,1.0f,0,0,1.0f);
break;
}
}
return true;
}
}
You can check the pointer id associated to the MotionEvent you've just received.
See the docs for more info:
https://developer.android.com/reference/android/view/MotionEvent.html#getPointerId(int)

ACTION_DRAG_STARTED gets called on all views

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

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.

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