Android drag imageview with finger behaves strange - java

I'm implementing imageview drag function to my application.
I have tried with below code but it's behaves strange.when I try to drag the image
it's changes the position and during the movement it's shows like zooming the image.
I want to move the image with finger smoothly.
please help me to solve this problem
#Override
public boolean onTouch(View v, MotionEvent event) {
final int X = (int) event.getRawX();
final int Y = (int) event.getRawY();
MarginLayoutParams marginParams = new MarginLayoutParams(mImagePreView.getLayoutParams());
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
_xDelta = X - marginParams.leftMargin;
_yDelta = Y - marginParams.topMargin;
break;
case MotionEvent.ACTION_MOVE:
marginParams.leftMargin = X-_xDelta;
marginParams.topMargin = Y - _yDelta;
marginParams.rightMargin = -250;
marginParams.bottomMargin = -250;
FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(marginParams);
mImagePreView.setLayoutParams(layoutParams);
break;
default:
break;
}
return true;
}

RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) mImagePreView.getLayoutParams();
layoutParams.leftMargin += offsetX;
layoutParams.topMargin += offsetY;
And there is error:
_xDelta = X - marginParams.leftMargin;
_yDelta = Y - marginParams.topMargin;
X - events in absolute coordinates, marginParams.leftMargin - coordinates are relative to the parent layout

Related

Restrict ImageView movement

I have to an ImageView named imgForeground which can be rotated, zoomed and moved but it can move to outside the screen. how can I restrict its movement not to go outside of screen? Is there any library for this? it is something like the apps that you can select a label, move and resize it and place it everywhere you want.
<ImageView
android:id="#+id/imgForground"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:src="#drawable/icon" />
This code for zoom, move and rotate:
#Override
public boolean onTouch(View v, MotionEvent event) {
ImageView view = (ImageView) v;
view.setScaleType(ImageView.ScaleType.MATRIX);
float scale;
// Dump touch event to log
dumpEvent(event);
// Handle touch events here...
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN: //first finger down only
savedMatrix.set(matrix);
start.set(event.getX(), event.getY());
Log.d(TAG, "mode=DRAG");
mode = DRAG;
break;
case MotionEvent.ACTION_POINTER_DOWN:
oldDist = spacing(event);
if (oldDist > 10f) {
savedMatrix.set(matrix);
midPoint(mid, event);
mode = ZOOM;
}
lastEvent = new float[4];
lastEvent[0] = event.getX(0);
lastEvent[1] = event.getX(1);
lastEvent[2] = event.getY(0);
lastEvent[3] = event.getY(1);
d = rotation(event);
break;
case MotionEvent.ACTION_UP: //first finger lifted
case MotionEvent.ACTION_POINTER_UP: //second finger lifted
mode = NONE;
Log.d(TAG, "mode=NONE");
break;
case MotionEvent.ACTION_MOVE:
if (mode == DRAG) {
// ...
matrix.set(savedMatrix);
matrix.postTranslate(event.getX() - start.x, event.getY()
- start.y);
} else if (mode == ZOOM && event.getPointerCount() == 2) {
float newDist = spacing(event);
matrix.set(savedMatrix);
if (newDist > 10f) {
scale = newDist / oldDist;
matrix.postScale(scale, scale, mid.x, mid.y);
}
if (lastEvent != null) {
newRot = rotation(event);
float r = newRot - d;
matrix.postRotate(r, view.getMeasuredWidth() / 2,
view.getMeasuredHeight() / 2);
}
}
break;
}
// Perform the transformation
view.setImageMatrix(matrix);
return true; // indicate event was handled
}
private float rotation(MotionEvent event) {
double delta_x = (event.getX(0) - event.getX(1));
double delta_y = (event.getY(0) - event.getY(1));
double radians = Math.atan2(delta_y, delta_x);
return (float) Math.toDegrees(radians);
}
private float spacing(MotionEvent event) {
float x = event.getX(0) - event.getX(1);
float y = event.getY(0) - event.getY(1);
return (float) Math.sqrt(x * x + y * y);
}
private void midPoint(PointF point, MotionEvent event) {
float x = event.getX(0) + event.getX(1);
float y = event.getY(0) + event.getY(1);
point.set(x / 2, y / 2);
}
/**
* Show an event in the LogCat view, for debugging
*/
private void dumpEvent(MotionEvent event) {
String names[] = {"DOWN", "UP", "MOVE", "CANCEL", "OUTSIDE",
"POINTER_DOWN", "POINTER_UP", "7?", "8?", "9?"};
StringBuilder sb = new StringBuilder();
int action = event.getAction();
int actionCode = action & MotionEvent.ACTION_MASK;
sb.append("event ACTION_").append(names[actionCode]);
if (actionCode == MotionEvent.ACTION_POINTER_DOWN
|| actionCode == MotionEvent.ACTION_POINTER_UP) {
sb.append("(pid ").append(
action >> MotionEvent.ACTION_POINTER_ID_SHIFT);
sb.append(")");
}
sb.append("[");
for (int i = 0; i < event.getPointerCount(); i++) {
sb.append("#").append(i);
sb.append("(pid ").append(event.getPointerId(i));
sb.append(")=").append((int) event.getX(i));
sb.append(",").append((int) event.getY(i));
if (i + 1 < event.getPointerCount())
sb.append(";");
}
sb.append("]");
Log.d(TAG, sb.toString());
}
Mobile device screen is a region of plane(x,y) where (0,0) coordinate is top-left corner. You need to calculate the imageView position w.r.t screen region. In your event handler, get the position of your imageView.
int[] location = new int[2];
view.getLocationOnScreen(location);
int x = location[0];
int y = location[1];
Now get the displayed size of an image inside the image view.
int ih=view.getMeasuredHeight();//height of imageView
int iw=view.getMeasuredWidth();//width of imageView
int iH=view.getDrawable().getIntrinsicHeight();//original height of underlying image
int iW=view.getDrawable().getIntrinsicWidth();//original width of underlying image
if (ih/iH<=iw/iW)
iw=iW*ih/iH; //rescaled width of image within ImageView
else
ih= iH*iw/iW; //rescaled height of image within ImageView
Now get the width and height of screen
DisplayMetrics displayMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
int deviceHeight = displayMetrics.heightPixels;
int deviceWidth = displayMetrics.widthPixels;
If imageView moves towards left
if(x>0)
//Move towards left functionality
If imageView moves towards top
if(y>0)
//Move towards top functionality
If imageView moves towards right
if(x+iw < deviceWidth)
//Move towards right functionality
If imageView moves towards bottom
if(y+ih < deviceHeight)
//Move towards right functionality

How can i get the dropped image x and y coordinates?

I have an image OnTouchListener i want to know the x and y coordinates of image dropped and can i get the coordinates in points? Please help!!
imageView.setOnTouchListener(onTouchListener());
private View.OnTouchListener onTouchListener() {
return (view, event) -> {
final int x = (int) event.getRawX();
final int y = (int) event.getRawY();
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
RelativeLayout.LayoutParams lParams = (RelativeLayout.LayoutParams)
view.getLayoutParams();
xDelta = x - lParams.leftMargin;
yDelta = y - lParams.topMargin;
break;
case MotionEvent.ACTION_UP:
break;
case MotionEvent.ACTION_MOVE:
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) view
.getLayoutParams();
layoutParams.leftMargin = x - xDelta;
layoutParams.topMargin = y - yDelta;
layoutParams.rightMargin = 0;
layoutParams.bottomMargin = 0;
view.setLayoutParams(layoutParams);
break;
}
mainLayout.invalidate();
return true;
};
}

Rotation of 3d object with touch in Android using "min3d" framework

I am facing problem for rotating 3d model object. when i load my 3d object in GLSerfaceView with Scene Object the rotation is not working properly.
when i touch the screen and move down means top to bottom then it is working fine as i expected. but when i touch the screen from left to right the it is not rotate as i expected.
glSurfaceView.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
switch(motionEvent.getAction()){
case MotionEvent.ACTION_DOWN:
previousX = motionEvent.getX();
previousY = motionEvent.getY();
break;
case MotionEvent.ACTION_UP:
break;
case MotionEvent.ACTION_MOVE:
x = motionEvent.getX();
y = motionEvent.getY();
float deltaX = (x - previousX) / density / 2f;
float deltaY = (y - previousY) / density / 2f;
objModel.rotation().x = objModel.rotation().x + deltaY;
objModel.rotation().y = objModel.rotation().y + deltaX;
previousX = x;
previousY = y;
break;
}
return true;
}
});

How to Draw on android ImageView after scaling it?

I have an ImageView and i want to zoom/drag on by two fingers and draw on it using one finger , but after scaling ImageView , bitmap coordinates and ImageView coordinates doesn't match , to solve this i provided onTouch like this :
#Override
public boolean onTouch(View v, MotionEvent event) {
ImageView view = (ImageView) v;
final int NONE = 0;
final int DRAW = 1;
final int PINCH = 2;
float x,y;
switch (event.getAction() & MotionEvent.ACTION_MASK){
case MotionEvent.ACTION_DOWN:
drawStartX = event.getX();
drawStartY = event.getY();
imageMode = DRAW;
break;
case MotionEvent.ACTION_POINTER_DOWN:
//drag
savedMatrix.set(matrix);
start.set(event.getX(), event.getY());
x = event.getX(0) - event.getX(1);
y = event.getY(0) - event.getY(1);
oldDistance = (float) Math.sqrt(x * x + y * y);
if (oldDistance > 5f) {
savedMatrix.set(matrix);
x = event.getX(0) + event.getX(1);
y = event.getY(0) + event.getY(1);
mid.set(x / 2, y / 2);
imageMode = PINCH;
}
break;
case MotionEvent.ACTION_UP:
imageMode = NONE;
break;
case MotionEvent.ACTION_POINTER_UP:
imageMode = NONE;
break;
case MotionEvent.ACTION_MOVE:
if (imageMode == DRAW) {
float drawEndX = event.getX();
float drawEndY = event.getY();
drawTest(drawStartX/bitmapScale - xTranslate, drawStartY/bitmapScale- yTranslate,drawEndX/bitmapScale - xTranslate,drawEndY/bitmapScale - yTranslate,0);
} else if (imageMode == PINCH) {
x = event.getX(0) - event.getX(1);
y = event.getY(0) - event.getY(1);
float newDistance = (float) Math.sqrt(x * x + y * y);
matrix.set(savedMatrix);
if(newDistance > 5f) {
//drag
float dx = event.getX() - start.x;
float dy = event.getY() - start.y;
matrix.postTranslate(dx, dy);
//zoom
float scale = (newDistance / oldDistance);
matrix.postScale(scale, scale);
}
//get matrix
float[] mat = new float[9];
matrix.getValues(mat);
bitmapScale = mat[0];
xTranslate = mat[2];
yTranslate = mat[5];
}
break;
}
view.setImageMatrix(matrix);
return true;
}
drawTest is just a void that draws a line.
pic
in before scale picture i drag my finger on imageview and line drawn in exact position , but after scaling i dragged on same position but result is not right
but it's not working properly. how can i fix it ?

Collision Between 2 views in android

I have 2 views in android and they are dragable.I want to detect collision between them.
Currently I am using this code to detect collision but I don't think its working .Please suggest what need to check the collision.
public boolean onTouch(View view, MotionEvent event) {
final int X = (int) event.getRawX();
final int Y = (int) event.getRawY();
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
RelativeLayout.LayoutParams lParams = (RelativeLayout.LayoutParams) view
.getLayoutParams();
_xDelta = X - lParams.leftMargin;
_yDelta = Y - lParams.topMargin;
break;
case MotionEvent.ACTION_UP:
break;
case MotionEvent.ACTION_POINTER_DOWN:
break;
case MotionEvent.ACTION_POINTER_UP:
break;
case MotionEvent.ACTION_MOVE:
RelativeLayout.LayoutParams ParamsA = (RelativeLayout.LayoutParams) view
.getLayoutParams();
ParamsA.leftMargin = X - _xDelta;
ParamsA.topMargin = Y - _yDelta;
ParamsA.rightMargin = -250;
ParamsA.bottomMargin = -250;
for (int i = 0; i < balls.size(); i++) {
if (balls.get(i).getTag() != view.getTag()) {
RelativeLayout.LayoutParams ParamsB = (RelativeLayout.LayoutParams) balls
.get(i).getLayoutParams();
Rect b = new Rect(ParamsB.leftMargin,ParamsB.topMargin,ParamsB.rightMargin,ParamsB.bottomMargin);
Rect a = new Rect(ParamsA.leftMargin,ParamsA.topMargin,ParamsA.rightMargin,ParamsA.bottomMargin);
if(a.intersect(b))
{
Toast.makeText(getApplicationContext(), "Collision Detected", Toast.LENGTH_SHORT).show();
}
}
}
view.setLayoutParams(ParamsA);
break;
}
// _root.invalidate();
return true;
}
"balls" is array of type "View" which are laying in the screen.
I just found solution myself it works perfect in all case.
public boolean CheckCollision(View v1,View v2) {
Rect R1=new Rect(v1.getLeft(), v1.getTop(), v1.getRight(), v1.getBottom());
Rect R2=new Rect(v2.getLeft(), v2.getTop(), v2.getRight(), v2.getBottom());
return R1.intersect(R2);
}

Categories

Resources