@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,当我在拖放操作后移开手指时,图像仍保持在相同的原始位置,但不在新位置。
答案 0 :(得分:0)
检查此样品是否有姜饼到上面的支撑物。 sample
如果您只需要支持上面的果冻豆,您可以使用Android库中的拖放,您可以从这篇文章中看到它
答案 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);