拖动后Android视图不可见

时间:2016-08-26 06:52:49

标签: android drag-and-drop

@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;
             }
         }
    });
 }
}

这是我的代码(实际上来自其他地方);这里我试图将一个图像从一个位置拖到另一个位置。但拖动图像后,它会从屏幕上消失。

我需要的是我想将图像视图从一个位置拖动到任何位置,并且在将其放入该新位置后它应该是可见的,并且新的位置坐标将保存在变量中。 当我关闭并重新启动应用程序时,图像应该处于我之前拖放操作中保存的新坐标

如果我将onTouch事件的可见性从INVISIBLE设置为VISIBLE,当我在拖放操作后移开手指时,图像仍保持在相同的原始位置,但不在新位置。

2 个答案:

答案 0 :(得分:0)

检查此样品是否有姜饼到上面的支撑物。 sample

如果您只需要支持上面的果冻豆,您可以使用Android库中的拖放,您可以从这篇文章中看到它

http://developer.android.com/guide/topics/ui/drag-drop.html

您可以在此处找到答案https://stackoverflow.com/a/25055408/4342876

答案 1 :(得分:0)

使用此代码可以拖放

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;
    }
}

使用这种方式

 MultiTouchListener mtl= new MultiTouchListener();
 imgPrint.setOnTouchListener(mtl);