Как получить правильные координаты (event.getX() / event.getY()) объекта с помощью OnTouchListener
и что я хочу именно то, чтобы показать часть растрового изображения через координаты(X,Y) объекта с OnTouchListener(оранжевый квадрат с точкой в центре).
Так что проблема в том, что я хочу нарисовать часть изображения, как это показано на изображении (красная площадь "Область, которую я хочу" показать).
Таким образом, в этом случае, исключенный результат (часть растрового изображения):
В настоящий момент я делаю так:
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;
}
}
И это не правильно.
Как я могу достичь этого? Перепробовал много формул, но не повезло. Какие-либо предложения?
PS Как я понимаю, event.getX ()/event.getY () получает относительные координаты (и мне не ясно, какие именно координаты получают от объекта просмотра изображений с помощью сенсорного слушателя (оранжевый квадрат с точкой в центре), я имею в виду его получить центр этого объекта или Top.Left углы (X,Y))?
3 ответа
Чтобы было легко решить эту проблему.
Решение:
У меня есть объект (оранжевый квадрат) с OnTouchListener(например, он четырехугольник с размером 50dp Высота/ 50dp Ширина).
Поэтому view.getX()/view.getY() принимает относительные координаты (центр) объекта (который имеет OnTouchListener).
Итак, что мне было нужно:
//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);
И это все.
Наслаждайтесь!
Извините, глядя на решение более подробно, я думаю, что нашел его, и я на работе, так что вы можете попробовать это:
использование event.getX()
не view.getX()
, view.getX()
возвращает позицию вида, которого вы касаетесь, а не интересующего вас события касания.
Это координата Y, которая, вероятно, будет инвертирована.
так event.getX()
позиция сенсорного события.
event.getY()
инвертированная позиция Y так getHeight() - event.getY()
даст вам позицию Y вы после.
РЕДАКТИРОВАТЬ
В случае MOTION_MOVE getX и getY возвращают самые последние и сохраняют исторические данные. я думаю, что самый последний из них самый ценный, потому что именно там вы будете рисовать.
В этом случае используйте пакетную квоту из документации:
Пакетная обработка - http://developer.android.com/reference/android/view/MotionEvent.html
Для эффективности события движения с ACTION_MOVE могут объединять несколько выборок движения в пределах одного объекта. Самые последние координаты указателя доступны с использованием getX(int) и getY(int). Более ранние координаты в пакете доступны с использованием getHistoricalX(int, int) и getHistoricalY(int, int). Координаты являются "историческими" только в том случае, если они старше, чем текущие координаты в пакете; однако они по-прежнему отличаются от любых других координат, о которых сообщалось в предыдущих событиях движения. Чтобы обработать все координаты в пакете во временном порядке, сначала используйте исторические координаты, а затем - текущие координаты.
Вы должны получить координаты, как это, это даст вам координаты со ссылкой для просмотра, а не на экране.
float xCord = event.getRawX()-v.getX();
float yCord = event.getRawY()-v.getY();
К сожалению, нет простого способа решить эту проблему, если вы хотите по-настоящему обратиться к событию в рамках представления. Это все еще происходит на Android Pie на некоторых аппаратных средствах. Единственный способ справиться с нечетными событиями касания - это сравнить последние 3 события, если во время ACTION_MOVE не было странных движений, перед тем, как пересмотреть позицию представления. Ниже приведен пример проверки события на круговом изображении. Предполагается, что вы создали новую временную переменную double[3]:
/**
* 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;
}