'm developing an application in which I'm pasting images, doing drawing and painting on canvas. This app can also Scale up/down the canvas or drag it to different location. My problem is: I can't get the correct canvas coordinates after scaling or dragging the canvas. I want to draw finger paint after the canvas is scaled or dragged but unable to retrieve the right place where i've touched...
#Override
public boolean onTouchEvent(MotionEvent event) {
scaleListener.onTouchEvent(event);
synchronized(thread.getSurfaceHolder()){
switch ( event.getAction() & MotionEvent.ACTION_MASK ){
case MotionEvent.ACTION_DOWN :
// Remember our initial down event location.
savedMatrix.set(m_matrix);
start.set(event.getX() , event.getY());
mode = DRAG;
break;
case MotionEvent.ACTION_POINTER_DOWN :
oldDist = spacing(event);
if (oldDist > 10f) {
savedMatrix.set(m_matrix);
m_matrix.getValues(matrixValues);
midPoint(mid, event);
mode = ZOOM;
}
break;
case MotionEvent.ACTION_UP :
case MotionEvent.ACTION_POINTER_UP :
mode = NONE;
break;
case MotionEvent.ACTION_MOVE :
if(mode==DRAG && isDragAllowd){
m_matrix.set(savedMatrix);
rebound(event.getX() , event.getY());
}
else if(mode==ZOOM){
float newDist = spacing(event);
if (newDist > 10f){
m_matrix.set(savedMatrix);
float scale = newDist/oldDist;
m_matrix.getValues(matrixValues);
float currentScale = matrixValues[Matrix.MSCALE_X];
// limit zoom
if (scale * currentScale > maxZoom){
scale = maxZoom / currentScale;
//scale = maxZoom;
}
else if (scale * currentScale < minZoom){
scale = minZoom / currentScale;
//scale = minZoom;
}
m_matrix.postScale(scale, scale, mid.x, mid.y);
m_matrix.getValues(matrixValues);
}
}
break;
}
return true; //done with this event so consume it
}
}
#Override
protected void onDraw(Canvas canvas){
super.onDraw(canvas);
canvas.drawColor(Color.WHITE);
canvas.drawBitmap(currentBitmap, m_matrix, null);
c2.drawColor(Color.BLACK);
commandManager.executeAll(c2); // Drawing all the Paints on Canvas c2
// Overlay bitmap it's a transparent layour
canvas.drawBitmap(overlayBitmap, 0, 0, pTouch);
}
when user zoom the bitmap he is not able to draw over it , after zooming drawing doesn't happen at proper place.
use the following equation for transformed the points, after that user will not face an any difficulty painting during zoom or after scrolling.
float f1 = (( motionEvent.getX() - m_transformedPoints[0] )/( m_transformedPoints[2] - m_transformedPoints[0] ))*currentBitmapWidth;
float f2 = (( motionEvent.getY() - m_transformedPoints[1] )/( m_transformedPoints[3] - m_transformedPoints[1] ))*currentBitmapHeight;
//calculate the transformed view in onDraw Method
this.m_transformedPoints[0] = 0.0F;
this.m_transformedPoints[1] = 0.0F;
this.m_transformedPoints[2] = currentBitmapWidth;
this.m_transformedPoints[3] = currentBitmapHeight;
this.m_matrix.mapPoints(this.m_transformedPoints);
Related
I was able to use a class created by one of the StackOverflow users for my needs.
The class was working fine, but It did not include scrolling(vertically, horizontally). I modified the following class by including the code under MotionEvent.Action_Up , which now provides scrolling both horizontally and vertically. The main problem I am having is with the ZOOM mode.
If you look closely, Zoom mode happens on MotionEvent.ACTION_POINTER_DOWN:
The logic is that it calculates the distance between two fingers and figures out the midpoint between them on the midpoint method. The center of the Zoom must be this midpoint. The code under MotionEvent.ACTION_POINTER_DOWN takes care of
saving and scaling the matrix.
This class is an ImageView and it hosts a drawable graph. The graph draws nicely and the horizontal and vertical scrolling are now enabled, but the zoom is causing problems: When the drawable loads and I try zooming it works fine, but if I try scrolling after that, the drawable gets lost in the view. Likewise, when I scroll at first and then Zoom, the drawable gets lost in the view very fast. It seems like the matrix changes the ImageView coordinates and therefore the midpoint is not the one that I need as the origin of the zoom.
Inside the drawable class onDraw() I implement the following logic:
canvas.save();
GraphImage.translateX = GraphImage.translateX + MainActivity.keeper14;
GraphImage.translateY = GraphImage.translateY + MainActivity.keeper15;
canvas.translate(GraphImage.translateX, GraphImage.translateY);
canvas.scale(GraphImage.main_scale, GraphImage.main_scale, MainActivity.middy.x , MainActivity.middy.y);
//do my draw calls here
MainActivity.keeper14 = GraphImage.translateX;
MainActivity.keeper15 = GraphImage.translateY;
canvas.restore();
As you can see, I use values updated inside the ImageView onTouch method.
I think the problem might be that the matrix is not coordinating well with the
canvas.scale() and canvas.translate() calls.
Here is the ImageView class. By the way, what is the purpose of the matrix in this class. Does it work only on the ImageView or also on the drawable that it has? Also, I use a scaleType = Matrix for this view.
public class GraphImage extends android.support.v7.widget.AppCompatImageView {
Paint paint;
Context c;
int color;
Matrix matrix;
Matrix savedMatrix;
static final int NONE = 0;
static final int DRAG = 1;
static final int ZOOM = 2;
int mode = NONE;
static PointF start,mid;
float oldDist;
static float main_scale;
static float translateX,translateY;
String savedItemClicked;
String TAG = "Batman";
float mx , my, curX, curY;
public GraphImage(Context context, AttributeSet attrs) {
super(context,attrs);
//all the variables are init here
setFocusable(true);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
dumpEvent(event);
// Handle touch events here...
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
mx = event.getX();
my = event.getY();
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);
Log.d(TAG, "oldDist=" + oldDist);
if (oldDist > 10f) {
savedMatrix.set(matrix);
midPoint(MainActivity.middy, event);
mode = ZOOM;
Log.d(TAG, "mode=ZOOM");
}
break;
case MotionEvent.ACTION_UP:
curX = event.getX();
curY = event.getY();
matrix.set(savedMatrix);
matrix.postTranslate(curX - mx, curY - my);
translateX = curX - mx;//event.getX() - start.x;
translateY = curY - my;//event.getY() - start.y;
this.invalidateDrawable(this.getDrawable());
break;
case MotionEvent.ACTION_POINTER_UP:
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);
translateX = event.getX() - start.x;
translateY = event.getY() - start.y;
this.invalidateDrawable(this.getDrawable());
*/
} else
if (mode == ZOOM) {
float newDist = spacing(event);
Log.d(TAG, "newDist=" + newDist);
if (newDist > 10f) {
matrix.set(savedMatrix);
float scale = newDist / oldDist;
main_scale = scale;
matrix.postScale(scale, scale, MainActivity.middy.x, MainActivity.middy.y);
this.invalidateDrawable(this.getDrawable());
}
}
break;
}
this.setImageMatrix(matrix);
//invalidate();
return true;
}
/** Determine the space between the first two fingers */
private float spacing(MotionEvent event) {
float x = event.getX(0) - event.getX(1);// Math.abs(event.getX() - mx);//event.getX(0) - event.getX(1);
float y = event.getY(0) - event.getY(1);//Math.abs(event.getY() - my);//event.getY(0) - event.getY(1);
return (float)Math.sqrt(x * x + y * y);
}
/** Calculate the mid point of the first two fingers */
private void midPoint(PointF point, MotionEvent event) {
float x = event.getX(0) + event.getX(1);//mx + event.getX();//event.getX(0) + event.getX(1);//
float y = event.getY(0) + event.getY(1);//my + event.getY();//event.getY(0) + event.getY(1);
point.set(x / 2, y / 2);
MainActivity.middy = point;
}
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());
}
}
Thanks for any suggestions
I added a few static variables on MainActivity class: translationXX, translationYY , drawing__scale.
Whenever ACTION_UP came up, I updated translationXX and translationYY, as such:
translationXX = translationXX + (curX - mx); //Likewise for translationYY
To coordinate with the changes that occurred whenever the drawable was invalidated:
canvas.translate(MainActivity.translationXX , MainActivity.translationYY);// inside onDraw of the drawable
Likewise, for zoom: Instead of MainActivity.middy as the midpoint of the finger placement on the screen that signified a zoom gesture, I went back to the variable static "mid" defined on GraphImage class. It happened that Mainactivity.middy kept the
old values assigned to it when the mode was ZOOM. Therefore, the zoom was really not doing good things. Inside the method midpoint of the GraphImage class I replaced the following line:
MainActivity.middy = point;
with the line:
mid = point;
To coordinate the zoom changes that took place inside GraphImage, inside my drawable class onDraw method I scaled the canvas, as such:
canvas.scale(MainActivity.drawing_scale, MainActivity.drawing_scale, GraphImage.mid.x,GraphImage.mid.y);//MainActivity.drawing_scale was updated when the mode was ZOOM inside the onTouch method of GraphImage
Also, inside ACTION_POINTER_UP: I had to invalidate the drawable since without this
the drawable would zoom as ACTION_MOVE was being called but then, it went back to its previous non-zoom state as soon as the fingers stopped touching the screen.
inside ACTION_POINTER_UP:
MainActivity.middy = mid; //this line was called on ACTION_MOVE when the mode = ZOOM
matrix.postScale(MainActivity.drawing_scale, MainActivity.drawing_scale,MainActivity.middy.x,MainActivity.middy.y)//middy was updated with the latest midpoint "mid" on a previous called to ZOOM inside ACTION_MOVE
After this line we simply call invalidate on the drawable. Also, I created a Boolean called moveit = false inside the onTouch(). Whenever ZOOM mode was on, moveit = true
Whenever ACTION_UP was called it would excute the code needed for the translation of the drawable only if(!moveit){//code that translates drawable}
This changes provide an acceptable view that zooms and scrolls in all directions. I might need to use the onFling() of the GestureDetector class to make it feel more realistic but it works very well. I avoided the nested scrolling (vertical and horizontal). But, I still will like to learn more about the details on using a matrix.
I need to click on particular item on the canvas while zooming and moving functionalities also enable for canvas. I can calculate the rectangle position while moving the canvas. There I just calculate the touch movement distance by (CurrenTouchXPosition - StartXPosition).
public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction();
int x = (int) event.getX();
int y = (int) event.getY();
float moveOffsetX = (event.getX() - start.x);
float moveOffsetY = (event.getY() - start.y);
Then,
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
savedMatrix.set(matrix);
start.set(event.getX(), event.getY());
mode = DRAG;
break;
case MotionEvent.ACTION_POINTER_DOWN:
break;
case MotionEvent.ACTION_UP:
Log.d(TAG, "action up");
secondRectUpperX = secondRectUpperX + moveOffsetX;
secondRectBottomX = secondRectBottomX + moveOffsetX;
secondRectUpperY = secondRectUpperY + moveOffsetY;
secondRectBottomY = secondRectBottomY + moveOffsetY;
This can identify the new canvas position of the rectangle. This works perfectly. I can identify the touch event of particular item while moving the canvas by this logic.
But now i need to calculate the rectangle position relative to the canvas, after zoom the canvas. Whats the maths behind the zooming. If anyone knows please help in this.
Thank you.
Finally I come up with a solution.
I translate my touch position screen coordinates to canvas coordinates.
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
...
break;
case MotionEvent.ACTION_POINTER_DOWN:
...
break;
case MotionEvent.ACTION_UP:
float []m = new float[9];
matrix.getValues(m);
float transX = m[Matrix.MTRANS_X] * -1;
float transY = m[Matrix.MTRANS_Y] * -1;
float scaleX = m[Matrix.MSCALE_X];
float scaleY = m[Matrix.MSCALE_Y];
lastTouchX = (int) ((event.getX() + transX) / scaleX);
lastTouchY = (int) ((event.getY() + transY) / scaleY);
lastTouchX = Math.abs(lastTouchX);
lastTouchY = Math.abs(lastTouchY);
Thanks for Andres Cardenas Pardo's answer here
I could able to get the touch position coordinates according to the canvas coordinates. Since i know the coordinates of my drawn object, i check whether the touch position is within the range of drawn object.
if((lastTouchX>=firstRectUpperX && firstRectBottomX>=lastTouchX) && (lastTouchY>=firstRectUpperY && firstRectBottomY>=lastTouchY)) {
isbtn1Clicked = true;
}
I have an imageview which I want to rotate, zoom and scale down or up and drag on user touch. So far all things are working perfect and in good way.
I have followed this code and some code others to get best result. now I want the image that is to be drag , move , zoom and rotate should be align to parents bottom. but when I Apply scale type to matrix the image shows on the top left corner on the screen when the screen is started. here is part of this code and you can also check in the link I shared, that guy is also using matrix as a scale type.
<ImageView
android:id="#+id/iv_overlay"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentBottom="true"
android:src="#drawable/groom01"
android:scaleType="matrix"
/>
if I remove the matrix as scale type it comes down but in the center but not in the bottom. and as i touch the imageview its looks like the matrixs get applied the picture flickers for a single sharp moment and comes again where we touch.
The flickering i due to the matrixs I believe which is set in the code also ,I think the image tries to go to left top of screen but comes down where we have clicked.
here is the part in on touch
#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(event1);
// 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) {
toggleSaveButtonState();
// ...
matrix.set(savedMatrix);
// matrix.postTranslate(event.getX() - start.x, event.getY()
// - start.y);
matrix.getValues(matrixValues);
matrixX = matrixValues[2];
matrixY = matrixValues[5];
width = matrixValues[0] * (((view).getDrawable()
.getIntrinsicWidth() / 2));
height = matrixValues[4] * (((view).getDrawable()
.getIntrinsicHeight() / 2));
dx = event.getX() - start.x;
dy = event.getY() - start.y;
float newX = event.getX() - start.x;
Log.v("bounds out", "matrixsX=" + matrixX+ " dx" + dx);
//if image will go outside left bound
if (matrixX + dx < 0-width){
dx = -matrixX-width;
Log.v("bounds", "matrixsX=" + matrixX + " dx" + dx + " width" + width + "image width = " + view.getWidth()/2);
// if (dx != -0.0) {
//
// // dx=(float)-0.0;
// }}
}
//if image will go outside right bound
if (matrixX + dx + width > view.getWidth()) {
dx = view.getWidth() - matrixX - width;
Log.v("bounds", "matrixsX=" + matrixX + " dx" + dx + " width" + width + "image width = " + view.getWidth());
}
//if image will go oustside top bound
if (matrixY + dy < 0) {
dy = -matrixY;
}
//if image will go outside bottom bound
if (matrixY + dy + height > view.getHeight()) {
dy = view.getHeight() - matrixY - height;
}
matrix.postTranslate(dx, dy);
} else if (mode == ZOOM && event.getPointerCount() == 2) {
float newDist = spacing(event);
matrix.set(savedMatrix);
if (newDist > 10f) {
scale = newDist / oldDist;
float[] values = new float[9];
matrix.getValues(values);
float currentScale = values[Matrix.MSCALE_X];
if (scale * currentScale > MAX_ZOOM) {
scale = MAX_ZOOM / currentScale;
}
else if (scale * currentScale < MIN_ZOOM)
{ scale = MIN_ZOOM / currentScale;}
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;
}
you can see the second line is
view.setScaleType(ImageView.ScaleType.MATRIX);
so if I do comment it , then Image view is unable to move rotate or to do anything.
so what I am supposed to do in this condition ? How can I set it to the bottom of screen and when the user touch it , he may be able to take it anywhere where he wants . Please show me a way to do it.
Just move image initially using matrix.postTranslate(leftOffset, topOffset); after it loaded.
See more info here
I am dragging , moving , zooming and rotating my image , all is working fine. but I have serious problem and that is my Image flicker due to some problem and starts appear from the top of screen. First let me show my code what I am doing and then I will tell you
**What I have done **
#Override
public boolean onTouch(View v, MotionEvent event) {
ImageView view = (ImageView) v;
view.setImageMatrix(matrix);
view.setScaleType(ImageView.ScaleType.MATRIX);
float scale;
// Dump touch event to log
// dumpEvent(event1);
// 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) {
toggleSaveButtonState();
// ...
matrix.set(savedMatrix);
// matrix.postTranslate(event.getX() - start.x, event.getY()
// - start.y);
matrix.getValues(matrixValues);
matrixX = matrixValues[2];
matrixY = matrixValues[5];
width = matrixValues[0] * (((view).getDrawable()
.getIntrinsicWidth() / 2));
height = matrixValues[4] * (((view).getDrawable()
.getIntrinsicHeight() / 2));
dx = event.getX() - start.x;
dy = event.getY() - start.y;
float newX = event.getX() - start.x;
Log.v("bounds out", "matrixsX=" + matrixX+ " dx" + dx);
//if image will go outside left bound
if (matrixX + dx < 0-width){
dx = -matrixX-width;
Log.v("bounds", "matrixsX=" + matrixX + " dx" + dx + " width" + width + "image width = " + view.getWidth()/2);
// if (dx != -0.0) {
//
// // dx=(float)-0.0;
// }}
}
//if image will go outside right bound
if (matrixX + dx + width > view.getWidth()) {
dx = view.getWidth() - matrixX - width;
Log.v("bounds", "matrixsX=" + matrixX + " dx" + dx + " width" + width + "image width = " + view.getWidth());
}
//if image will go oustside top bound
if (matrixY + dy < 0) {
dy = -matrixY;
}
//if image will go outside bottom bound
if (matrixY + dy + height > view.getHeight()) {
dy = view.getHeight() - matrixY - height;
}
matrix.postTranslate(dx, dy);
} else if (mode == ZOOM && event.getPointerCount() == 2) {
float newDist = spacing(event);
matrix.set(savedMatrix);
if (newDist > 10f) {
scale = newDist / oldDist;
float[] values = new float[9];
matrix.getValues(values);
float currentScale = values[Matrix.MSCALE_X];
if (scale * currentScale > MAX_ZOOM) {
scale = MAX_ZOOM / currentScale;
}
else if (scale * currentScale < MIN_ZOOM)
{ scale = MIN_ZOOM / currentScale;}
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
}
This piece of code I think you can found almost all over every where I have slightly updated it to put some limits such as going off the screen etc.
**Problem **
When I start my application I want it to be appear in bottom but some how it sticks to middle , and when I touch the image view it flicks , it looks like that it starts it self from top corner and then come down to the point where we have touched it and Also it becomes bigger on some devices and smaller on some devices.
I think this is due to this line.
view.setScaleType(ImageView.ScaleType.MATRIX);
if I remove this line and put this line in xml such as
android:scaleType="matrix"
Then My image stick to the top which I do not want to be happen
So what can I do and How can I make things possible this is what I want
What I Want
I want my Image to show on the bottom of the screen
I want my image never gets flicking effect and should never be re sized
I want the touch to be happen when touch on the image inside the Image view
Please tell me How can I get my desired results.
In my application i want to get image x and y coordinates after drag and zoom the image. So I am using the following code.In my xml i have taken relative layout.This is relative layout.
<RelativeLayout
android:id="#+id/image"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_above="#+id/buttonlayout"
android:layout_marginTop="0dp" >
</RelativeLayout>
In this relative layout i want to drag the image and zoom the image.So that's why I have created Image view programatically and apply the touch listener to that image view.This is the oncreate code.
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.inventory_submit_images_activity);
relImage=(RelativeLayout) findViewById(R.id.image);
imgMarker = new ImageView(this);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.FILL_PARENT,
RelativeLayout.LayoutParams.FILL_PARENT);
params.leftMargin = 0;
params.topMargin = 0;
relImage.addView(imgMarker, params);
imgMarker.setScaleType(ImageView.ScaleType.MATRIX);
bmdragImage=BitmapFactory.decodeResource(getResources(), R.drawable.image_marker);
height = bmdragImage.getHeight();
width = bmdragImage.getWidth();
imgMarker.setImageBitmap(bmdragImage);
imgMarker.setOnTouchListener(this);
}
And this is the ontouch method and related methods.
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
ImageView view = (ImageView) v;
view.setScaleType(ImageView.ScaleType.MATRIX);
float scale = 0;
layoutParamss = (RelativeLayout.LayoutParams)
v.getLayoutParams();
// Handle touch events here...
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN: // first finger down only
x=(int) event.getX();
y=(int) event.getY();
savedMatrix.set(matrix);
start.set(event.getX(), event.getY());
Log.d(TAG, "mode=DRAG"); // write to LogCat
mode1 = DRAG1;
break;
case MotionEvent.ACTION_UP: // first finger lifted
x_cordinate=(int) event.getX();
y_cordinate=(int) event.getY();
Log.e("x_cordinate==",""+x_cordinate+" "+bmdragImage.getHeight());
Log.e("y_cordinate==",""+y_cordinate+" "+bmdragImage.getWidth());
break;
case MotionEvent.ACTION_POINTER_UP: // second finger lifted
mode1 = NONE1;
Log.d(TAG, "mode1=NONE1");
break;
case MotionEvent.ACTION_POINTER_DOWN: //second finger down..
oldDist = spacing(event);
Log.d(TAG, "oldDist=" + oldDist);
if (oldDist > 10f) {
savedMatrix.set(matrix);
midPoint(mid, event);
mode1 = ZOOM1;
Log.d(TAG, "mode=ZOOM" );
}
break;
case MotionEvent.ACTION_MOVE:
Log.e("ACTION_MOVE","ACTION_MOVE");
if (mode1 == DRAG1){
matrix.set(savedMatrix);
matrix.postTranslate(event.getX() - start.x, event.getY() - start.y); // create the transformation in the matrix of points
}
else if (mode1 == ZOOM1){
// pinch zooming
float newDist = spacing(event);
Log.d(TAG, "newDist=" + newDist);
if (newDist > 5f){
matrix.set(savedMatrix);
scale = newDist / oldDist; // setting the scaling of the image..
matrix.postScale(scale, scale, mid.x, mid.y);
height=(int) (bmdragImage.getHeight()*scale);
width=(int) (bmdragImage.getWidth()*scale);
Log.e("height int===="+scale,""+height);
Log.e("width int====="+scale,""+width);
}
}
break;
}
view.setImageMatrix(matrix); // display the transformation on screen
return true; // indicate event was handled
}
/** Determine the space between the first two fingers */
private float spacing(MotionEvent event) {
float x = event.getX(0) - event.getX(1);
float y = event.getY(0) - event.getY(1);
return FloatMath.sqrt(x * x + y * y);
}
/** Calculate the mid point of the first two fingers */
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);
}
This code is dragging and zooming is working fine. But my problem is getting x coordinate and y coordinate after drag the image.These x and y values are getting wrong. Because where ever i touch the image with in the relative layout, dragging is working.Because of these code in oncreate of image view params. So x and y values are getting wrong.
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.FILL_PARENT,
RelativeLayout.LayoutParams.FILL_PARENT);
If i change the image layout params to wrap contnet like the bellow,the image dragging is with in that area only. And zooming also not working properly. But my requirement is drag the image total relative layout.And get the x and y coordinates of image view.
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
Suggestions are appreciated..