0
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    img=(ImageView)findViewById(R.id.imageView);

    img.setOnLongClickListener(new View.OnLongClickListener() {
        @Override
        public boolean onLongClick(View v) {
            ClipData.Item item = new ClipData.Item((CharSequence)v.getTag());
            String[] mimeTypes = {ClipDescription.MIMETYPE_TEXT_PLAIN};

            ClipData dragData = new ClipData(v.getTag().toString(),mimeTypes, item);
            View.DragShadowBuilder myShadow = new View.DragShadowBuilder(img);

            v.startDrag(dragData,myShadow,null,0);
            return true;
        }
    });

    img.setOnDragListener(new View.OnDragListener() {
        @Override
        public boolean onDrag(View v, DragEvent event) {
            switch(event.getAction()){            
                case DragEvent.ACTION_DRAG_STARTED:
                    layoutParams = (RelativeLayout.LayoutParams)v.getLayoutParams();
                    break;

                case DragEvent.ACTION_DRAG_ENTERED:
                    int x_cord = (int) event.getX();
                    int y_cord = (int) event.getY();
                    break;

                case DragEvent.ACTION_DRAG_EXITED :
                    x_cord = (int) event.getX();
                    y_cord = (int) event.getY();
                    layoutParams.leftMargin = x_cord;
                    layoutParams.topMargin = y_cord;
                    v.setLayoutParams(layoutParams);
                    break;

                case DragEvent.ACTION_DRAG_LOCATION  :
                    x_cord = (int) event.getX();
                    y_cord = (int) event.getY();
                    break;

                case DragEvent.ACTION_DRAG_ENDED   :
                    break;

                case DragEvent.ACTION_DROP:
                    break;
                default: break;
            }
            return true;
        }
    });

    img.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            if (event.getAction() == MotionEvent.ACTION_DOWN) {
                ClipData data = ClipData.newPlainText("", "");
                View.DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(img);

                img.startDrag(data, shadowBuilder, img, 0);
                img.setVisibility(View.INVISIBLE);
                return true;
            } else  {
                return false;
             }
         }
    });
 }
}

This is my code (actually taken from somewhere else); here am trying to drag one image from one location to another location. But after dragging the image it disappeared from the screen.

What I need is I want to drag an image view from one location to any location and it should be visible after dropping it in that new location and the new location coordinates will be saved in variables. When I close and relaunch the application, the image should be at new coordinates which are saved in my previous drag and drop operation

If I set the visibility in onTouch event from INVISIBLE to VISIBLE, When I remove my finger after drag and drop operation the image still remains in same original position but not at the new location.

halfer
  • 19,824
  • 17
  • 99
  • 186
Veena
  • 31
  • 7

1 Answers1

0

Use this code it allow's drag and zoom

package com.print.dev.CustomeListener;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import com.print.dev.R;
import com.print.dev.utils.Utils;

import java.util.ArrayList;



public class MultiTouchListener implements View.OnTouchListener {

private static final int INVALID_POINTER_ID = -1;
public boolean isRotateEnabled = true;
public boolean isTranslateEnabled = true;
public boolean isScaleEnabled = true;
public float minimumScale = 0.5f;
public float maximumScale = 10.0f;
private int mActivePointerId = INVALID_POINTER_ID;
private float mPrevX;
private float mPrevY;
private ScaleGestureDetector mScaleGestureDetector;
private static View previousView, CurrentView;
private static Boolean isFirstTime = true;

public MultiTouchListener() {
    mScaleGestureDetector = new ScaleGestureDetector(
            new ScaleGestureListener());
}

protected void setRandomPosition(View view) {

    TransformInfo randomInfo = new TransformInfo();

    randomInfo.deltaScale = Utils.generatRandomPositiveNegitiveValue(2, 0);
    randomInfo.deltaAngle = Utils.generatRandomPositiveNegitiveValue(4, 2);
    randomInfo.deltaX = Utils.generatRandomPositiveNegitiveValue(4, 2);
    randomInfo.deltaY = Utils.generatRandomPositiveNegitiveValue(4, 2);
    randomInfo.pivotX = Utils.generatRandomPositiveNegitiveValue(4, 2);
    randomInfo.pivotY = Utils.generatRandomPositiveNegitiveValue(4, 2);
    randomInfo.minimumScale = minimumScale;
    randomInfo.maximumScale = 2f;

    move(view, randomInfo);
}

private static float adjustAngle(float degrees) {
    if (degrees > 180.0f) {
        degrees -= 360.0f;
    } else if (degrees < -180.0f) {
        degrees += 360.0f;
    }

    return degrees;
}

private static void move(View view, TransformInfo info) {
    computeRenderOffset(view, info.pivotX, info.pivotY);
    adjustTranslation(view, info.deltaX, info.deltaY);

    // Assume that scaling still maintains aspect ratio.
    float scale = view.getScaleX() * info.deltaScale;
    scale = Math.max(info.minimumScale, Math.min(info.maximumScale, scale));
    view.setScaleX(scale);
    view.setScaleY(scale);

    float rotation = adjustAngle(view.getRotation() + info.deltaAngle);
    view.setRotation(rotation);
}

private static void adjustTranslation(View view, float deltaX, float deltaY) {
    float[] deltaVector = {deltaX, deltaY};
    view.getMatrix().mapVectors(deltaVector);
    view.setTranslationX(view.getTranslationX() + deltaVector[0]);
    view.setTranslationY(view.getTranslationY() + deltaVector[1]);
}

private static void computeRenderOffset(View view, float pivotX,
                                        float pivotY) {
    if (view.getPivotX() == pivotX && view.getPivotY() == pivotY) {
        return;
    }

    float[] prevPoint = {0.0f, 0.0f};
    view.getMatrix().mapPoints(prevPoint);

    view.setPivotX(pivotX);
    view.setPivotY(pivotY);

    float[] currPoint = {0.0f, 0.0f};
    view.getMatrix().mapPoints(currPoint);

    float offsetX = currPoint[0] - prevPoint[0];
    float offsetY = currPoint[1] - prevPoint[1];

    view.setTranslationX(view.getTranslationX() - offsetX);
    view.setTranslationY(view.getTranslationY() - offsetY);
}

@Override
public boolean onTouch(View view, MotionEvent event) {
    if (view.getTag() != null) {
        Utils.REMOVE_VIEW = view;

    }
    if (isFirstTime) {
        Log.e("Inside", "when first time");
        CurrentView = view;
        isFirstTime = false;
        CurrentView.setBackgroundResource(R.drawable.border);
        return true;
    } else {
        if (view.getId() != CurrentView.getId()) {
            Log.e("action", "second time");
            previousView = CurrentView;
            previousView.setBackgroundResource(R.drawable.tv_border);
            CurrentView = view;
            CurrentView.setBackgroundResource(R.drawable.border);
        }

    }

    int action = event.getAction();

    switch (action & event.getActionMasked()) {
        case MotionEvent.ACTION_DOWN: {
            Log.e("action", "button down");
            mPrevX = event.getX();
            mPrevY = event.getY();

            // Save the ID of this pointer.
            mActivePointerId = event.getPointerId(0);
            break;
        }
        case MotionEvent.ACTION_OUTSIDE:

            break;
        case MotionEvent.ACTION_MOVE: {
            // Find the index of the active pointer and fetch its position.
            int pointerIndex = event.findPointerIndex(mActivePointerId);
            if (pointerIndex != -1) {
                float currX = event.getX(pointerIndex);
                float currY = event.getY(pointerIndex);

                // Only move if the ScaleGestureDetector isn't processing a
                // gesture.
                if (!mScaleGestureDetector.isInProgress()) {
                    adjustTranslation(view, currX - mPrevX, currY - mPrevY);
                }
            }

            break;
        }
        case MotionEvent.ACTION_POINTER_DOWN:

            Log.e("action", "button pinter down");
            break;
        case MotionEvent.ACTION_HOVER_EXIT:
            Log.e("action", "button hover exit");
            break;
        case MotionEvent.ACTION_HOVER_ENTER:
            Log.e("action", "button hover enter");
            break;
        case MotionEvent.ACTION_CANCEL:
            Log.e("action", "button cancel");
            mActivePointerId = INVALID_POINTER_ID;
            break;

        case MotionEvent.ACTION_UP:
            Log.e("action", "button up");
            // view.setBackgroundResource(R.drawable.tv_border);
            mActivePointerId = INVALID_POINTER_ID;
            break;

        case MotionEvent.ACTION_POINTER_UP: {
            Log.e("action", "button pointer up");
            // Extract the index of the pointer that left the touch sensor.
            // view.setBackgroundResource(R.drawable.tv_border);
            int pointerIndex = (action & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
            int pointerId = event.getPointerId(pointerIndex);
            if (pointerId == mActivePointerId) {
                // This was our active pointer going up. Choose a new
                // active pointer and adjust accordingly.
                int newPointerIndex = pointerIndex == 0 ? 1 : 0;
                mPrevX = event.getX(newPointerIndex);
                mPrevY = event.getY(newPointerIndex);
                mActivePointerId = event.getPointerId(newPointerIndex);
            }

            break;
        }
        case MotionEvent.ACTION_BUTTON_PRESS:
            Log.e("action", "button press");
            break;
        case MotionEvent.ACTION_BUTTON_RELEASE:
            Log.e("action", "button release");
            break;
    }
    mScaleGestureDetector.onTouchEvent(view, event);

    return true;
}

private class ScaleGestureListener extends
        ScaleGestureDetector.SimpleOnScaleGestureListener {

    private float mPivotX;
    private float mPivotY;
    private Vector2D mPrevSpanVector = new Vector2D();

    @Override
    public boolean onScaleBegin(View view, ScaleGestureDetector detector) {
        mPivotX = detector.getFocusX();
        mPivotY = detector.getFocusY();
        mPrevSpanVector.set(detector.getCurrentSpanVector());
        return true;
    }

    @Override
    public boolean onScale(View view, ScaleGestureDetector detector) {
        TransformInfo info = new TransformInfo();
        info.deltaScale = isScaleEnabled ? detector.getScaleFactor() : 1.0f;
        info.deltaAngle = isRotateEnabled ? Vector2D.getAngle(
                mPrevSpanVector, detector.getCurrentSpanVector()) : 0.0f;
        info.deltaX = isTranslateEnabled ? detector.getFocusX() - mPivotX
                : 0.0f;
        info.deltaY = isTranslateEnabled ? detector.getFocusY() - mPivotY
                : 0.0f;
        info.pivotX = mPivotX;
        info.pivotY = mPivotY;
        info.minimumScale = minimumScale;
        info.maximumScale = maximumScale;

        move(view, info);
        return false;
    }
}

private class TransformInfo {

    public float deltaX;
    public float deltaY;
    public float deltaScale;
    public float deltaAngle;
    public float pivotX;
    public float pivotY;
    public float minimumScale;
    public float maximumScale;
}
}



 package com.print.dev.CustomeListener;

import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

/**
 * Created by Mobile First on 13-Aug-16.
 */
public class ScaleGestureDetector {
    private static final String TAG = "ScaleGestureDetector";


    public interface OnScaleGestureListener {

        public boolean onScale(View view, ScaleGestureDetector detector);


        public boolean onScaleBegin(View view, ScaleGestureDetector detector);

        public void onScaleEnd(View view, ScaleGestureDetector detector);
    }

    public static class SimpleOnScaleGestureListener implements OnScaleGestureListener {

        public boolean onScale(View view, ScaleGestureDetector detector) {
            return false;
        }

        public boolean onScaleBegin(View view, ScaleGestureDetector detector) {
            return true;
        }

        public void onScaleEnd(View view, ScaleGestureDetector detector) {
            // Intentionally empty
        }
    }


    private static final float PRESSURE_THRESHOLD = 0.67f;

    private final OnScaleGestureListener mListener;
    private boolean mGestureInProgress;

    private MotionEvent mPrevEvent;
    private MotionEvent mCurrEvent;

    private Vector2D mCurrSpanVector;
    private float mFocusX;
    private float mFocusY;
    private float mPrevFingerDiffX;
    private float mPrevFingerDiffY;
    private float mCurrFingerDiffX;
    private float mCurrFingerDiffY;
    private float mCurrLen;
    private float mPrevLen;
    private float mScaleFactor;
    private float mCurrPressure;
    private float mPrevPressure;
    private long mTimeDelta;

    private boolean mInvalidGesture;

    // Pointer IDs currently responsible for the two fingers controlling the gesture
    private int mActiveId0;
    private int mActiveId1;
    private boolean mActive0MostRecent;

    public ScaleGestureDetector(OnScaleGestureListener listener) {
        mListener = listener;
        mCurrSpanVector = new Vector2D();
    }

    public boolean onTouchEvent(View view, MotionEvent event) {
        final int action = event.getActionMasked();

        if (action == MotionEvent.ACTION_DOWN) {
            reset(); // Start fresh
        }

        boolean handled = true;
        if (mInvalidGesture) {
            handled = false;
        } else if (!mGestureInProgress) {
            switch (action) {
                case MotionEvent.ACTION_DOWN: {
                    mActiveId0 = event.getPointerId(0);
                    mActive0MostRecent = true;
                }
                break;

                case MotionEvent.ACTION_UP:
                    reset();
                    break;

                case MotionEvent.ACTION_POINTER_DOWN: {
                    // We have a new multi-finger gesture
                    if (mPrevEvent != null) mPrevEvent.recycle();
                    mPrevEvent = MotionEvent.obtain(event);
                    mTimeDelta = 0;

                    int index1 = event.getActionIndex();
                    int index0 = event.findPointerIndex(mActiveId0);
                    mActiveId1 = event.getPointerId(index1);
                    if (index0 < 0 || index0 == index1) {
                        // Probably someone sending us a broken event stream.
                        index0 = findNewActiveIndex(event, mActiveId1, -1);
                        mActiveId0 = event.getPointerId(index0);
                    }
                    mActive0MostRecent = false;

                    setContext(view, event);

                    mGestureInProgress = mListener.onScaleBegin(view, this);
                    break;
                }
            }
        } else {
            // Transform gesture in progress - attempt to handle it
            switch (action) {
                case MotionEvent.ACTION_POINTER_DOWN: {
                    // End the old gesture and begin a new one with the most recent two fingers.
                    mListener.onScaleEnd(view, this);
                    final int oldActive0 = mActiveId0;
                    final int oldActive1 = mActiveId1;
                    reset();

                    mPrevEvent = MotionEvent.obtain(event);
                    mActiveId0 = mActive0MostRecent ? oldActive0 : oldActive1;
                    mActiveId1 = event.getPointerId(event.getActionIndex());
                    mActive0MostRecent = false;

                    int index0 = event.findPointerIndex(mActiveId0);
                    if (index0 < 0 || mActiveId0 == mActiveId1) {
                        // Probably someone sending us a broken event stream.
                        index0 = findNewActiveIndex(event, mActiveId1, -1);
                        mActiveId0 = event.getPointerId(index0);
                    }

                    setContext(view, event);

                    mGestureInProgress = mListener.onScaleBegin(view, this);
                }
                break;

                case MotionEvent.ACTION_POINTER_UP: {
                    final int pointerCount = event.getPointerCount();
                    final int actionIndex = event.getActionIndex();
                    final int actionId = event.getPointerId(actionIndex);

                    boolean gestureEnded = false;
                    if (pointerCount > 2) {
                        if (actionId == mActiveId0) {
                            final int newIndex = findNewActiveIndex(event, mActiveId1, actionIndex);
                            if (newIndex >= 0) {
                                mListener.onScaleEnd(view, this);
                                mActiveId0 = event.getPointerId(newIndex);
                                mActive0MostRecent = true;
                                mPrevEvent = MotionEvent.obtain(event);
                                setContext(view, event);
                                mGestureInProgress = mListener.onScaleBegin(view, this);
                            } else {
                                gestureEnded = true;
                            }
                        } else if (actionId == mActiveId1) {
                            final int newIndex = findNewActiveIndex(event, mActiveId0, actionIndex);
                            if (newIndex >= 0) {
                                mListener.onScaleEnd(view, this);
                                mActiveId1 = event.getPointerId(newIndex);
                                mActive0MostRecent = false;
                                mPrevEvent = MotionEvent.obtain(event);
                                setContext(view, event);
                                mGestureInProgress = mListener.onScaleBegin(view, this);
                            } else {
                                gestureEnded = true;
                            }
                        }
                        mPrevEvent.recycle();
                        mPrevEvent = MotionEvent.obtain(event);
                        setContext(view, event);
                    } else {
                        gestureEnded = true;
                    }

                    if (gestureEnded) {
                        // Gesture ended
                        setContext(view, event);

                        // Set focus point to the remaining finger
                        final int activeId = actionId == mActiveId0 ? mActiveId1 : mActiveId0;
                        final int index = event.findPointerIndex(activeId);
                        mFocusX = event.getX(index);
                        mFocusY = event.getY(index);

                        mListener.onScaleEnd(view, this);
                        reset();
                        mActiveId0 = activeId;
                        mActive0MostRecent = true;
                    }
                }
                break;

                case MotionEvent.ACTION_CANCEL:
                    mListener.onScaleEnd(view, this);
                    reset();
                    break;

                case MotionEvent.ACTION_UP:
                    reset();
                    break;

                case MotionEvent.ACTION_MOVE: {
                    setContext(view, event);

                    // Only accept the event if our relative pressure is within
                    // a certain limit - this can help filter shaky data as a
                    // finger is lifted.
                    if (mCurrPressure / mPrevPressure > PRESSURE_THRESHOLD) {
                        final boolean updatePrevious = mListener.onScale(view, this);

                        if (updatePrevious) {
                            mPrevEvent.recycle();
                            mPrevEvent = MotionEvent.obtain(event);
                        }
                    }
                }
                break;
            }
        }

        return handled;
    }

    private int findNewActiveIndex(MotionEvent ev, int otherActiveId, int removedPointerIndex) {
        final int pointerCount = ev.getPointerCount();

        // It's ok if this isn't found and returns -1, it simply won't match.
        final int otherActiveIndex = ev.findPointerIndex(otherActiveId);

        // Pick a new id and update tracking state.
        for (int i = 0; i < pointerCount; i++) {
            if (i != removedPointerIndex && i != otherActiveIndex) {
                return i;
            }
        }
        return -1;
    }

    private void setContext(View view, MotionEvent curr) {
        if (mCurrEvent != null) {
            mCurrEvent.recycle();
        }
        mCurrEvent = MotionEvent.obtain(curr);

        mCurrLen = -1;
        mPrevLen = -1;
        mScaleFactor = -1;
        mCurrSpanVector.set(0.0f, 0.0f);

        final MotionEvent prev = mPrevEvent;

        final int prevIndex0 = prev.findPointerIndex(mActiveId0);
        final int prevIndex1 = prev.findPointerIndex(mActiveId1);
        final int currIndex0 = curr.findPointerIndex(mActiveId0);
        final int currIndex1 = curr.findPointerIndex(mActiveId1);

        if (prevIndex0 < 0 || prevIndex1 < 0 || currIndex0 < 0 || currIndex1 < 0) {
            mInvalidGesture = true;
            Log.e(TAG, "Invalid MotionEvent stream detected.", new Throwable());
            if (mGestureInProgress) {
                mListener.onScaleEnd(view, this);
            }
            return;
        }

        final float px0 = prev.getX(prevIndex0);
        final float py0 = prev.getY(prevIndex0);
        final float px1 = prev.getX(prevIndex1);
        final float py1 = prev.getY(prevIndex1);
        final float cx0 = curr.getX(currIndex0);
        final float cy0 = curr.getY(currIndex0);
        final float cx1 = curr.getX(currIndex1);
        final float cy1 = curr.getY(currIndex1);

        final float pvx = px1 - px0;
        final float pvy = py1 - py0;
        final float cvx = cx1 - cx0;
        final float cvy = cy1 - cy0;

        mCurrSpanVector.set(cvx, cvy);

        mPrevFingerDiffX = pvx;
        mPrevFingerDiffY = pvy;
        mCurrFingerDiffX = cvx;
        mCurrFingerDiffY = cvy;

        mFocusX = cx0 + cvx * 0.5f;
        mFocusY = cy0 + cvy * 0.5f;
        mTimeDelta = curr.getEventTime() - prev.getEventTime();
        mCurrPressure = curr.getPressure(currIndex0) + curr.getPressure(currIndex1);
        mPrevPressure = prev.getPressure(prevIndex0) + prev.getPressure(prevIndex1);
    }

    private void reset() {
        if (mPrevEvent != null) {
            mPrevEvent.recycle();
            mPrevEvent = null;
        }
        if (mCurrEvent != null) {
            mCurrEvent.recycle();
            mCurrEvent = null;
        }
        mGestureInProgress = false;
        mActiveId0 = -1;
        mActiveId1 = -1;
        mInvalidGesture = false;
    }


    public boolean isInProgress() {
        return mGestureInProgress;
    }


    public float getFocusX() {
        return mFocusX;
    }

    public float getFocusY() {
        return mFocusY;
    }


    public float getCurrentSpan() {
        if (mCurrLen == -1) {
            final float cvx = mCurrFingerDiffX;
            final float cvy = mCurrFingerDiffY;
            mCurrLen = (float) Math.sqrt(cvx * cvx + cvy * cvy);
        }
        return mCurrLen;
    }

    public Vector2D getCurrentSpanVector() {
        return mCurrSpanVector;
    }


    public float getCurrentSpanX() {
        return mCurrFingerDiffX;
    }

    public float getCurrentSpanY() {
        return mCurrFingerDiffY;
    }


    public float getPreviousSpan() {
        if (mPrevLen == -1) {
            final float pvx = mPrevFingerDiffX;
            final float pvy = mPrevFingerDiffY;
            mPrevLen = (float) Math.sqrt(pvx * pvx + pvy * pvy);
        }
        return mPrevLen;
    }


    public float getPreviousSpanX() {
        return mPrevFingerDiffX;
    }


    public float getPreviousSpanY() {
        return mPrevFingerDiffY;
    }


    public float getScaleFactor() {
        if (mScaleFactor == -1) {
            mScaleFactor = getCurrentSpan() / getPreviousSpan();
        }
        return mScaleFactor;
    }


    public long getTimeDelta() {
        return mTimeDelta;
    }


    public long getEventTime() {
        return mCurrEvent.getEventTime();
    }
}

    package com.print.dev.CustomeListener;

import android.annotation.SuppressLint;
import android.graphics.PointF;

/**
 * Created by Mobile First on 13-Aug-16.
 */
@SuppressLint("ParcelCreator")
public class Vector2D  extends PointF {

    public Vector2D() {
        super();
    }

    public Vector2D(float x, float y) {
        super(x, y);
    }

    public static float getAngle(Vector2D vector1, Vector2D vector2) {
        vector1.normalize();
        vector2.normalize();
        double degrees = (180.0 / Math.PI) * (Math.atan2(vector2.y, vector2.x) - Math.atan2(vector1.y, vector1.x));
        return (float) degrees;
    }

    public void normalize() {
        float length = (float) Math.sqrt(x * x + y * y);
        x /= length;
        y /= length;
    }
}

Use this way

 MultiTouchListener mtl= new MultiTouchListener();
 imgPrint.setOnTouchListener(mtl);
Milan Pansuriya
  • 2,521
  • 1
  • 19
  • 33