I want to use both pinch zoom and drag n drop on the same view in my app.
I am able to implement them individually but when I try to use both it doesn't work.
Here is the code for dragging
class MyClickListener implements OnLongClickListener {
@Override
public boolean onLongClick(View view) {
ClipData.Item item = new ClipData.Item((CharSequence) view.getTag());
String[] mimeTypes = { ClipDescription.MIMETYPE_TEXT_PLAIN };
ClipData data = new ClipData(view.getTag().toString(), mimeTypes,
item);
DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(view);
view.startDrag(data, // data to be dragged
shadowBuilder, // drag shadow
view, // local data about the drag and drop operation
0 // no needed flags
);
return true;
}
}
This works fine when I use on a non custom view without pinch to zoom.
When I use a custom view which has a scalegesture listener and then set MyClickListener as its LongClickListener I only get the scaling function and no drag is started.
I tried to add the drag code directly into the custom view after detecting a long press on the view
public class TouchImageView extends View {
long time = 0;
private Drawable image;
private float scaleFactor = 1.0f;
private ScaleGestureDetector scaleGestureDetector;
public TouchImageView(Context context) {
super(context);
}
public TouchImageView(Context context, Drawable mImage) {
super(context);
image = mImage;
setFocusable(true);
image.setBounds(0, 0, image.getIntrinsicWidth(),
image.getIntrinsicHeight());
scaleGestureDetector = new ScaleGestureDetector(context,
new ScaleListener());
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// Set the image bounderies
canvas.save();
canvas.scale(scaleFactor, scaleFactor);
image.draw(canvas);
canvas.restore();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getPointerCount() > 1) {
scaleGestureDetector.onTouchEvent(event);
invalidate();
} else {
int action = MotionEventCompat.getActionMasked(event);
switch(action){
case MotionEvent.ACTION_DOWN:
time = SystemClock.elapsedRealtime();
Log.i(EJ.TAG, time+"");
break;
case MotionEvent.ACTION_UP:
long time1 = SystemClock.elapsedRealtime() - time;
if(time1 >= 1000){
ClipData.Item item = new ClipData.Item((CharSequence) this.getTag());
String[] mimeTypes = { ClipDescription.MIMETYPE_TEXT_PLAIN };
ClipData data = new ClipData(this.getTag().toString(), mimeTypes,
item);
DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(this);
this.startDrag(data, // data to be dragged
shadowBuilder, // drag shadow
this, // local data about the drag and drop operation
0 // no needed flags
);
//Toast.makeText(context, "Long press", Toast.LENGTH_SHORT).show();
return true;
}
break;
}
}
return true;
}
private class ScaleListener extends
ScaleGestureDetector.SimpleOnScaleGestureListener {
@Override
public boolean onScale(ScaleGestureDetector detector) {
scaleFactor *= detector.getScaleFactor();
// don't let the object get too small or too large.
scaleFactor = Math.max(0.1f, Math.min(scaleFactor, 5.0f));
invalidate();
return true;
}
}
}
I'm not sure if this is the right approach. Any help on this is appreciated