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.
Related
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;
}
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..
I have a circle and triangle images inside a view pager.
I am trying to move the triangle image along the circle image using on-touch listener.
But when i move the triangle, the screen/fragment also moves to the next as i am using a view pager.
What do i do so that when the on-touch listener of the triangle or circle is called then view pager on touch listener is not called.
UPDATE: ADDING CODE
mCurrTempIndicator.setOnTouchListener(new MyOnTouchListener());
private class MyOnTouchListener implements OnTouchListener {
private double startAngle;
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
if (mThermostatCentreXOnScreen == 0 || mThermostatCentreYOnScreen == 0){
int centerXOnImage=mThermostatBgrd.getWidth()/2;
int centerYOnImage=mThermostatBgrd.getHeight()/2;
mThermostatCentreXOnScreen=mThermostatBgrd.getLeft()+centerXOnImage;
mThermostatCentreYOnScreen=mThermostatBgrd.getTop()+centerYOnImage;
mStartPosX = event.getRawX();
mStartPosY = event.getRawY();
float dx = event.getX() - mThermostatCentreXOnScreen;
float dy = event.getY() - mThermostatCentreYOnScreen;
float r = FloatMath.sqrt((dx * dx) + (dy * dy));
////
break;
case MotionEvent.ACTION_MOVE:
dx = event.getX() - mThermostatCentreXOnScreen;
dy = event.getY() - mThermostatCentreYOnScreen;
r = FloatMath.sqrt((dx * dx) + (dy * dy));
mEndPosX = event.getX();
mEndPosY = event.getY();
case MotionEvent.ACTION_UP:
allowRotating = true;
break;
}
return true;
}
Thanks and regards,
Sunny
If you return true in your onTouchListener for the triangle and circle it will consume the event and the parent won't receive it.
We have a longpress detection on a button. When detected, the view should be dismissed (back to the game view) and the object chosen with the button shall be at the coordinates of the longpress. That's the easy part, the hard part is to then change the coordinates with the finger, without releasing it.
Okay so i'm trying to reformulate this: We have two views displayed on top of eachother. What we want is a longclick detected in the top view, to then dismiss the top view, and without releasing the finger, get touchevents in the bottom view.
This is our class gameView: (this code contains a lot of code unneccesay for the problem)
#Override
public boolean onTouchEvent(MotionEvent event) {
gestureDetector.onTouchEvent(event);
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
mode = DRAG;
//We assign the current X and Y coordinate of the finger to startX and startY minus the previously translated
//amount for each coordinates This works even when we are translating the first time because the initial
//values for these two variables is zero.
startX = event.getX() - previousTranslateX;
startY = event.getY() - previousTranslateY;
break;
case MotionEvent.ACTION_MOVE:
translateX = event.getX() - startX;
translateY = event.getY() - startY;
gestureHandler.setTranslation(translateX, translateY);
//We cannot use startX and startY directly because we have adjusted their values using the previous translation values.
//This is why we need to add those values to startX and startY so that we can get the actual coordinates of the finger.
double distance = Math.sqrt(Math.pow(event.getX() - (startX + previousTranslateX), 2) +
Math.pow(event.getY() - (startY + previousTranslateY), 2)
);
if(distance > 0) {
dragged = true;
}
break;
case MotionEvent.ACTION_POINTER_DOWN:
mode = ZOOM;
scaleToX = event.getX();
scaleToY = event.getY();
break;
case MotionEvent.ACTION_UP:
mode = NONE;
dragged = false;
//All fingers went up, so let's save the value of translateX and translateY into previousTranslateX and
//previousTranslate
previousTranslateX = translateX;
previousTranslateY = translateY;
int x = (int)((-translateX/scaleFactorX)+(event.getX()/this.scaleFactorX));
int y = (int)((-translateY/scaleFactorY)+(event.getY()/this.scaleFactorY));
map.click(getContext(), x, y);
for(CastleTile castleTile : map.getCastleTiles()) {
if(castleTile.getRect().contains((int)((-translateX/scaleFactorX)+(event.getX()/this.scaleFactorX)), (int)((-translateY/scaleFactorY)+(event.getY()/this.scaleFactorY)))){
Log.d("Castle to your service", "Boes");
castleSettings.show();
}
}
break;
case MotionEvent.ACTION_POINTER_UP:
mode = DRAG;
//This is not strictly necessary; we save the value of translateX and translateY into previousTranslateX
//and previousTranslateY when the second finger goes up
previousTranslateX = translateX;
previousTranslateY = translateY;
break;
}
detector.onTouchEvent(event);
//We redraw the canvas only in the following cases:
//
// o The mode is ZOOM
// OR
// o The mode is DRAG and the scale factor is not equal to 1 (meaning we have zoomed) and dragged is
// set to true (meaning the finger has actually moved)
if ((mode == DRAG && scaleFactorX != 1f && scaleFactorY != 1f && dragged) || mode == ZOOM) {
invalidate();
}
return true;
}
#Override
public boolean onLongClick(View v) {
castleSettings.dismiss();
return true;
}
And this is the gestureHandler:
public void onLongPress(MotionEvent event) {
map.longClick(context, (int)((-translateX/scaleFactorX)+(event.getX()/this.scaleFactorX)), (int)((-translateY/scaleFactorY)+(event.getY()/this.scaleFactorY)));
}
Sorry for eventual lack of information or bad explaination :)
How can i determine the direction of gesture ? The use case is shown in the image link. what is the right logic for detecting in which direction the person is trying to move the ball in the circular path ? I have called the direction method in move gesture...Can someone help me fine tune this ... ?
http://www.shrenikvikam.com/wp-content/uploads/2011/04/214e422a43E11S3.png-150x134.png
private String getDirection(float firstTouchX, float finalTouchX){
if((firstTouchX - finalTouchX)>0)
return "Left";
else
return "Right";
}
#Override
public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction();
switch (action) {
// MotionEvent class constant signifying a finger-down event
case MotionEvent.ACTION_DOWN: {
Log.d("ACTION DOWN","Value ->");
final float x = event.getX();
final float y = event.getY();
initialTouchX = x;
initialTouchY = y;
break;
}
// MotionEvent class constant signifying a finger-drag event
case MotionEvent.ACTION_MOVE: {
final float x = event.getX();
final float y = event.getY();
final String direction = getDirection(initialTouchX,x);
Log.d("ACTION MOVE","diff in initial and cur value of x ->" + direction + (initialTouchX - x) + initialTouchX + "y->" + initialTouchY);
break;
}
// MotionEvent class constant signifying a finger-up event
case MotionEvent.ACTION_UP: {
Log.d("ACTION UP","Value ->");
break;
}
}
return true;
}
It seems like the slope of the line formed by the two touch points should be equal to the tangent of the circle at that point. This link has most of the math to pursue such a solution
I have used the difference between angles to the center point of the circle with good success. That may be the way to go as well.
If you are trying to determine which way to move the ball around the ciricle, it doesn't make sense for getDirection to return "Left" and "Right", it should be working with "Clockwise" and "Counterclockwise". Consider, for example, when the ball is at the 20 marker in your image: At this point every point on the circle is "Right" of where you are now...
In order to determine if the ball is moving clockwise or counterclockwise you need to consider both the x and y co-ordinates of the touch points, the x co-ordinate alone is not sufficient. You also need to know where the centre of the circle is. I would suggest in order to determine the direction of movement, you calculate the angle between the touch points and the centre of the circle.
prevTouchX = event.getHistoricalX(event.getHistorySize()-1);
currentTouchX = event.getX();
if(currentTouchX<prevTouchX){
Log.d("LEFT",event.getX()+" and "+event.getY());
}
if(currentTouchX>prevTouchX){
Log.d("RIGHT",event.getX()+" and "+event.getY());
}
Similarly for UP/DOWN
I use this code for rotating a view. It works very well. Have a look at this;
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
firstX = event.getX();
firstY = event.getY();
break;
case MotionEvent.ACTION_MOVE:
int dx =(int) (event.getX() - firstX);
int dy =(int) (event.getY() - firstY);
Log.d("Distance Rotate Touch",Integer.toString((int) (firstX-dx)));
if (signView.getRotation()<180){
if (firstX - dx > 15 && firstY - dy > 15 ){
View.setRotation(signView.getRotation()-5);
}else if(firstX - dx < -15 && firstY - dy < 15 ){
View.setRotation(signView.getRotation()+5);
}
}else {
if (firstX - dx > 10 && firstY - dy < -10 ){
View.setRotation(signView.getRotation()+5);
}else if(firstX-dx < -10 && firstY - dy < -15 ){
View.setRotation(signView.getRotation()-5);
}
}
break;
default: return true;
}