Reputation: 771
I set a drag listener to an ImageView
in my app, but when I click it, I don't want it to center the image based on where I pressed. It does this:
https://gfycat.com/ConstantDisguisedKudu
Basically, if I press on bottom right
of the image, it takes where I press as central point
and moves image's center point
on that exact location. But I don't want it to do that. If I press on bottom right
, it shouldn't auto move itself and I can drag the image from that point. I don't think any code is necessary but just in case:
@Override
public boolean onDrag(View v, DragEvent event) {
switch (event.getAction()) {
// Signal for the start of drag and drop operation
case DragEvent.ACTION_DRAG_STARTED: {
// do nothing
break;
}
// The drag point has entered the bounding box of the View
case DragEvent.ACTION_DRAG_ENTERED: {
// do nothing
break;
}
// The user has moved the drag shadow outside the bounding box of the view
case DragEvent.ACTION_DRAG_EXITED: {
// do nothing
break;
}
// Drag shadow has been released, the drag point is within the bounding box of the view
case DragEvent.ACTION_DROP: {
// Get the image and its position
ImageView view = (ImageView) event.getLocalState();
int position = (int) view.getTag(R.id.piece_position);
/**
* If it is dropped on the left pane, remove it from its parent and also
* remove the bitmap at the position and notify the adapter.
* Add it to the left pane and set the position.
*/
if (v == puzzlePane) {
ViewGroup viewgroup = (ViewGroup) view.getParent();
viewgroup.removeView(view);
if (position != -1) {
pieces.remove(position);
mAdapter.notifyDataSetChanged();
}
FrameLayout containView = (FrameLayout) v;
containView.addView(view);
view.setVisibility(View.VISIBLE);
view.setTag(R.id.piece_state, "left");
view.setTag(R.id.piece_position, -1);
view.setOnLongClickListener(null);
view.setOnTouchListener(mAdapter);
} else {
view.setVisibility(View.VISIBLE);
view.setTag(R.id.piece_state, "right");
view.setOnTouchListener(null);
view.setOnLongClickListener(mAdapter);
}
Log.d(MyDragListener.class.getSimpleName(), view.getTag(R.id.piece_state) + "");
view.setX(event.getX() - (view.getWidth() / 2));
view.setY(event.getY() - (view.getHeight() / 2));
break;
}
// The drag and drop operation has concluded
case DragEvent.ACTION_DRAG_ENDED: {
// do nothing
break;
}
}
return true;
}
Upvotes: 0
Views: 909
Reputation: 5096
You need to extend View.DragShadowBuilder , and send the location of your finger relative to the continer. Something like that:
//where you trigger the dragging
View yourImage; //
yourImage.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
final ClipData dragData = new ClipData("label", new String[]{ClipDescription.MIMETYPE_TEXT_PLAIN}, null);
startDrag(dragData, // the data to be dragged
new MyDragShadowBuilder(v, event.getX(), event.getY()), // the drag shadow builder
null,
0 // flags (not currently used, set to 0)
);
return true;
}
});
And the class:
private static class MyDragShadowBuilder extends View.DragShadowBuilder {
int width, height, relativeX, relativeY;
public MyDragShadowBuilder(View v, float relativeX,float relativeY) {
super(v);
this.relativeX = (int) relativeX;
this.relativeY = (int) relativeY;
width = (v.getWidth());
height = (v.getHeight());
}
@Override
public void onProvideShadowMetrics (@NonNull Point size, @NonNull Point touch){
size.set(width, height);
touch.set(relativeX, relativeY);
}
}
Upvotes: 2