I have this :
and what i want exactly is that to show portion of Bitmap via coords(X,Y) of object with OnTouchListener(orange square with dot in center).
So the problem is that i want to draw portion of image like it shows on image(Red square "Area that i want" to show).
So in this case,excepted result is(portion of bitmap) :
At current moment i'm doing like this:
public boolean onTouch(View view, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_MOVE:
Bitmap mBitmap = Bitmap.createBitmap(sourceBitmap,view.getX() - view.getWidth(),view.getY()-view.getHeight(),250,250);
//other stuff to fill this portion of bitmap
break;
}
return true;
}
}
And it's not correct.
how can i achieve this?
Tried a lot of formulas,but no luck. Any suggestions?
PS As i understand event.getX()/event.getY() is getting relative coords(and it's not clear for me,what exactly coords getting from object of imageview with touch listener(orange square with dot in center),i mean its getting center of this objects or Top.Left corners(X,Y)) ?
Sorry, whilst looking in more detail coming up with solution i think i found it and I am at work so can you try this:
Use event.getX()
not view.getX()
. the view.getX()
returns position of the view you are touching not the touch event you are interested in.
This is the Y coordinate which will likely be inverted.
so event.getX()
is the position of the touch event.
event.getY()
is the inverted Y position so getHeight() - event.getY()
will give you the Y position you are after.
EDIT
In the case of MOTION_MOVE getX and getY return the most recent and maintains historical data. i guess the most recent one is the most valuable as that's where you will be drawing.
In that case use batching quote from documentation:
Batching - http://developer.android.com/reference/android/view/MotionEvent.html
For efficiency, motion events with ACTION_MOVE may batch together
multiple movement samples within a single object. The most current
pointer coordinates are available using getX(int) and getY(int).
Earlier coordinates within the batch are accessed using
getHistoricalX(int, int) and getHistoricalY(int, int). The coordinates
are "historical" only insofar as they are older than the current
coordinates in the batch; however, they are still distinct from any
other coordinates reported in prior motion events. To process all
coordinates in the batch in time order, first consume the historical
coordinates then consume the current coordinates.
You have to get the coordinates like this , it will give you coordinates with reference to view not the screen.
float xCord = event.getRawX()-v.getX();
float yCord = event.getRawY()-v.getY();
So it was simple to resolve this problem.
Solution:
I have an object(orange square) with OnTouchListener(for e.g. he's an quad with size 50dp Height/ 50dp Width).
So view.getX()/view.getY() takes relative coords(center) of object(that have OnTouchListener).
So what i needed:
//imageview parameters ,where i will show this part of bitmap
int Width = img.getWidth();
int Height = img.getHeight();
//after this,i make margin of my coords,via this simple formula -> Current Coord X - Width / 2 (same for Y)
Bitmap mBitmap = Bitmap.createBitmap(sourceBitmap,view.getX() - Width / 2,view.getY()-Height / 2,Width,Height);
And that is all.
Enjoy!
Sadly there's no easy way of solving this if you want to really address the event within the bounds of the view. This is still occurring on Android Pie on some hardware. The only way to address odd touch events is to compare the last 3 events if there are no odd movements during ACTION_MOVE before rending the position of the view. Below is a sample when checking the event on a circular view. Assumption is that you created a new double[3] temporary variable :
/**
* This detects if your finger movement is a result of an actual raw touch event of if it's from a view jitter.
* This uses 3 events of rotation as temporary storage so that differentiation between swapping touch events can be determined.
*
* @param newRotationValue
*/
private boolean isRotationTouchEventConsistent(final double newRotationValue) {
double evalValue = newRotationValue;
if (Double.compare(newRotationStore[2], newRotationStore[1]) != 0) {
newRotationStore[2] = newRotationStore[1];
}
if (Double.compare(newRotationStore[1], newRotationStore[0]) != 0) {
newRotationStore[1] = newRotationStore[0];
}
newRotationStore[0] = evalValue;
if (Double.compare(newRotationStore[2], newRotationStore[0]) == 0
|| Double.compare(newRotationStore[1], newRotationStore[0]) == 0
|| Double.compare(newRotationStore[2], newRotationStore[1]) == 0
//Is the middle event the odd one out
|| (newRotationStore[0] > newRotationStore[1] && newRotationStore[1] < newRotationStore[2])
|| (newRotationStore[0] < newRotationStore[1] && newRotationStore[1] > newRotationStore[2])
) {
return false;
}
return true;
}