I am trying out simple program that have sounds based if moved. so at the beginning I have down - which play sound 1 and from then every move it is keeps playing a sound. At count 4 I have made it to play from start.
here is the problem: When I don't move my finger and hold it in the same place the sound still keeps 1 by 1 - Figured out the x and y value firing. How do I stop this??
OnTouchListener MyOnTouchListener= new OnTouchListener()
{
public boolean onTouch(View view, MotionEvent event)
{
switch(event.getAction() & MotionEvent.ACTION_MASK)
{
case MotionEvent.ACTION_DOWN:
x = (int) event.getX();
y = (int) event.getY();
oldval = x+y;
break;
case MotionEvent.ACTION_MOVE:
{
Log.e("X value", "X is "+x);
Log.e("Y value", "Y is "+y);
try
{
Thread.sleep(500);
} catch (InterruptedException e) {
}
int newval= (int) (event.getX() + event.getY());
if(Math.abs(oldval-newval)>50)
{
Log.e("First", "next button");
longpressCount++;
if(longpressCount==1)
{
Log.e("1", "BUTTON PRESSED");
}
else if(longpressCount==2)
{
Log.e("2", "BUTTON PRESSED");
}
else if(longpressCount==3)
{
Log.e("3", "BUTTON PRESSED");
}
else if(longpressCount==4)
{
Log.e("4", "BUTTON PRESSED");
longpressCount = 0;
}
}
break;
}
}
return true;
}
MOVE is very sensitive and will continue to be called as long as your finger is down. Set Old Value at the end of the sound playing code so it will only play if moved another 50 distance from that spot.
Something like this.
OnTouchListener MyOnTouchListener= new OnTouchListener()
{
public boolean onTouch(View view, MotionEvent event)
{
switch(event.getAction() & MotionEvent.ACTION_MASK)
{
case MotionEvent.ACTION_DOWN:
x = (int) event.getX();
y = (int) event.getY();
oldval = x+y;
break;
case MotionEvent.ACTION_MOVE:
{
Log.e("X value", "X is "+x);
Log.e("Y value", "Y is "+y);
try
{
Thread.sleep(500);
} catch (InterruptedException e) {
}
int newval= (int) (event.getX() + event.getY());
if(Math.abs(oldval-newval)>50)
{
Log.e("First", "next button");
longpressCount++;
if(longpressCount==1)
{
Log.e("1", "BUTTON PRESSED");
}
else if(longpressCount==2)
{
Log.e("2", "BUTTON PRESSED");
}
else if(longpressCount==3)
{
Log.e("3", "BUTTON PRESSED");
}
else if(longpressCount==4)
{
Log.e("4", "BUTTON PRESSED");
longpressCount = 0;
}
oldval = event.getX() + event.getY();
}
break;
}
}
return true;
}
Related
I click 2 fingers on a SurfaceView at a Time, i want get X,Y of 2 Points:
This is my code, but it only get X,Y of 1 Finger.
How can get X,Y of 2 Fingers at a Time?
#Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
int ipoiter = event.getPointerCount();
Toast.makeText(getContext(), String.valueOf(ipoiter), Toast.LENGTH_SHORT).show();
for(int i=0;i<ipoiter;i++){
int x= (int)event.getX(i);
int y = (int)event.getY(i);
Toast.makeText(getContext(), String.valueOf(x), Toast.LENGTH_SHORT).show();
}
}
}
I had try below code but action=0, so can't process.
public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction() & MotionEvent.ACTION_MASK;
Toast.makeText(getContext(), String.valueOf(action), Toast.LENGTH_SHORT).show();
if (action == MotionEvent.ACTION_POINTER_DOWN) {
int ipoiter = event.getPointerCount();
Toast.makeText(getContext(), String.valueOf(ipoiter), Toast.LENGTH_SHORT).show();
for(int i=0;i<ipoiter;i++){
int x= (int)event.getX(i);
int y = (int)event.getY(i);
Toast.makeText(getContext(), String.valueOf(x), Toast.LENGTH_SHORT).show();
}
}
}
ACTION_POINTER_DOWN is triggered for each newly touched point on screen.
to get the all touch points try something as follows.
You will get the active finger points in mActivePointers
private SparseArray<PointF> mActivePointers = new SparseArray<PointF>();
#Override
public boolean onTouchEvent(MotionEvent event) {
// get pointer index from the event object
int pointerIndex = event.getActionIndex();
// get pointer ID
int pointerId = event.getPointerId(pointerIndex);
// get masked (not specific to a pointer) action
int maskedAction = event.getActionMasked();
switch (maskedAction) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_POINTER_DOWN: {
// We have a new pointer. Lets add it to the list of pointers
PointF f = new PointF();
f.x = event.getX(pointerIndex);
f.y = event.getY(pointerIndex);
mActivePointers.put(pointerId, f);
break;
}
case MotionEvent.ACTION_MOVE: { // a pointer was moved
for (int size = event.getPointerCount(), i = 0; i < size; i++) {
PointF point = mActivePointers.get(event.getPointerId(i));
if (point != null) {
point.x = event.getX(i);
point.y = event.getY(i);
}
}
break;
}
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
case MotionEvent.ACTION_CANCEL: {
mActivePointers.remove(pointerId);
break;
}
}
invalidate();
return true;
}
Source : Check this
So I have a view under my view, that I need to pass to the pinch to zoom. BUT, if the user double taps, than I do not want to pass the double tap to my second view. Because I need the functionality that is set on a double tap to be ignored.
The only problem is that that functionality is set to be called on 2 ACTION_DOWN events received from the touch listener.
Now I tried to make a logic to prevent from doubletapping to work, but make the pinch to zoom work, but it still isn't perfect. IF I tap with 2 fingers, 1 in 1 place of the screen, and then the other in another place, a bit further it will get it as a double tap, and not consume the Touch, as I need.
This is the code for my touchEventListener:
viewTop.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
Log.i("","double touch event action: ===========================");
Log.i("","double touch event test action:" + event.getPointerId(0));
if(event.getPointerId(0) == 0) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
if (secondPressed) {
Log.i("", "double touch test : FIRST FINGER: CONSUMED TRUE");
timeLastTouch = System.currentTimeMillis();
return true;
}else {
Log.i("", "double touch DOWN : " + timeLastTouch + "... time passed: " + (System.currentTimeMillis() - timeLastTouch) + "..... location diff: " + (event.getX() - xLastTouch));
Log.i("", "double touch test XLAST : " + xLastTouch + "/" + yLastTouch + " ... XLAST 2 : " + xLastTouch2 + "/" + yLastTouch2);
if (System.currentTimeMillis() - timeLastTouch < 1000 && Math.abs(event.getX() - xLastTouch) < 150 && Math.abs(event.getY() - yLastTouch) < 150) {
Log.i("", "double touch test TRUE DOWN");
secondPressed = true;
timeLastTouch = System.currentTimeMillis();
xLastTouch = event.getX();
yLastTouch = event.getY();
return true;
} else if (System.currentTimeMillis() - timeLastTouch < 1000 && Math.abs(event.getX() - xLastTouch2) < 150 && Math.abs(event.getY() - yLastTouch2) < 150) {
Log.i("", "double touch test TRUE DOWN");
secondPressed = true;
timeLastTouch = System.currentTimeMillis();
return true;
} else {
timeLastTouch = System.currentTimeMillis();
if(xLastTouch2 == -1) {
xLastTouch2 = event.getX();
yLastTouch2 = event.getY();
}else {
xLastTouch = event.getX();
yLastTouch = event.getY();
}
Log.i("", "double touch test FALSE DOWN!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! X : " + event.getX() + "/" + event.getY() + ".... TIME: " + (System.currentTimeMillis() - timeLastTouch));
Log.i("", "double touch test FALSE DOWN!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! DIFF LAST TOUCH: " + Math.abs(event.getX() - xLastTouch) + "/" + Math.abs(event.getY() - yLastTouch));
Log.i("", "double touch test FALSE DOWN!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! DIFF LAST TOUCH2: " + Math.abs(event.getX() - xLastTouch2) + "/" + Math.abs(event.getY() - yLastTouch2));
return false;
}
}
} else if (event.getAction() == MotionEvent.ACTION_UP) {
handlerTouch.removeCallbacksAndMessages(null);
Log.i("", "double touch test FALSE UP");
timeLastTouch = System.currentTimeMillis();
handlerTouch.postDelayed(new Runnable() {
#Override
public void run() {
resetTouches();
Log.i("", "double touch test : SECOND PRESSED BECOMES FALSE");
}
}, 300);
return true;
} else {
timeLastTouch = System.currentTimeMillis();
xLastTouch = event.getX();
yLastTouch = event.getY();
Log.i("", "double touch ELSE FALSE");
return false;
}
}else if(event.getPointerId(0) == 1){
timeLastTouch = System.currentTimeMillis();
if(event.getAction() == MotionEvent.ACTION_DOWN) {
xLastTouch2 = event.getX();
yLastTouch2 = event.getY();
secondPressed = true;
return false;
}else if(event.getAction() == MotionEvent.ACTION_UP){
Log.i("","double touch test : SECONDARY FINGER: SECOND PRESSED BECOMES FALSE");
handlerTouch.postDelayed(new Runnable() {
#Override
public void run() {
resetTouches();
Log.i("", "double touch test : SECOND PRESSED BECOMES FALSE");
}
}, 300);
}else {
Log.i("","double touch test : SECONDARY FINGER: SECOND PRESSED BECOMES TRUE");
secondPressed = true;
}
return false;
}else {
timeLastTouch = System.currentTimeMillis();
secondPressed = true;
return false;
}
}
});
Where resetTouches is:
private void resetTouches() {
xLastTouch = -1f;
yLastTouch = -1f;
xLastTouch2 = -1f;
yLastTouch2 = -1f;
secondPressed = false;
}
Now I'm kinda blocked here, and don't know what or how to change in order to prevent the double tap to work. Is there by any change any implementation of this that might be easier? What could I change to improve on this?
This did it for me:
final ScaleGestureDetector mScaleDetector = new ScaleGestureDetector(InCallActivity.this, new ScaleGestureDetector.OnScaleGestureListener() {
#Override
public void onScaleEnd(ScaleGestureDetector detector) {
Log.i("", "double touch test2 onScaleEnd: " + detector.getScaleFactor());
app.TouchEvent(0, 1, (int) xFinger1, (int) yFinger1);
if (xFinger2 != 0) {
app.TouchEvent(1, 1, (int) xFinger2, (int) yFinger2);
} else scale(1, (int) (yFinger1));
}
#Override
public boolean onScaleBegin(ScaleGestureDetector detector) {
Log.i("", "double touch test2 onScaleBegin: " + detector.getScaleFactor());
app.TouchEvent(0, 0, (int) xFinger1, (int) yFinger1);
if (xFinger2 != 0) {
app.TouchEvent(1, 0, (int) xFinger2, (int) yFinger2);
} else app.TouchEvent(1, 0, (int) xFinger1, (int) yFinger1);
return true;
}
#Override
public boolean onScale(ScaleGestureDetector detector) {
Log.i("", "double touch test2 zoom ongoing, scale: " + detector.getScaleFactor());
app.TouchEvent(0, 2, (int) xFinger1, (int) yFinger1);
if (xFinger2 != 0) {
app.TouchEvent(1, 2, (int) xFinger2, (int) yFinger2);
} else {
scaleValue = detector.getScaleFactor();
scale(2, (int) (yFinger1));
}
return false;
}
});
viewTop.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
Log.i("", "double touch test2 ON TOUCH: " + event.getPointerId(0) + "x/y: " + event.getX() + "/" + event.getY());
xFinger1 = event.getX(0);
yFinger1 = event.getY(0);
try {
xFinger2 = event.getX(1);
yFinger2 = event.getY(1);
mScaleDetector.onTouchEvent(event);
} catch (Exception e) {
return logicFor1Finger(event, e);
}
return true;
}
});
Here is my code:
public boolean onTouch(View v, MotionEvent event) {
switch(event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
Log.d("getButtonCode", "catch ACTION_DOWN");
break;
case MotionEvent.ACTION_POINTER_DOWN:
Log.d("getButtonCode", "catch ACTION_POINTER_DOWN");
break;
case MotionEvent.ACTION_POINTER_UP:
Log.d("getButtonCode", "catch ACTION_POINTER_UP");
break;
case MotionEvent.ACTION_UP:
Log.d("getButtonCode", "catch ACTION_UP");
case MotionEvent.ACTION_CANCEL:
Log.d("getButtonCode", "catch ACTION_CANCEL");
case MotionEvent.ACTION_MOVE:
break;
default:
break;
}
return true;
}
and I never catch ACTION_POINTER_DOWN and ACTION_POINTER_UP. If I remove breakfrom ACTION_DOWN, I catch ACTION_POINTER_DOWN always after ACTION_DOWN, even if it is first pointer. I think it should be so: first pointer catch only ACTION_DOWN, every next pointer only ACTION_POINTER_DOWN, if non-primary pointer has gone up, I should catch ACTION_POINTER_UP.
But it doesn't work. What is wrong in my code?
PS: I saw other similar questions, but no answer helped me.
Instead of using a switch statement, I flowed through a series of if statements. This let me test against event.getAction() or event.getActionMasked() and it allowed multiple possible actions through at once.
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
startingX = (int) event.getX();
startingY = (int) event.getY();
}
if(event.getAction() == MotionEvent.ACTION_MOVE) {
int scaleX = 1;
int scaleY = 1;
if(touchStateScale == true){
scaleX = (int) (event.getX(0) - event.getX(1));
scaleY = (int) (event.getY(0) - event.getY(1));
}
int endingX = (int) event.getX();
int endingY = (int) event.getY();
int newX = endingX-startingX;
int newY = endingY-startingY;
((ImageView) v).setImageBitmap(drawNewImageScaled(baseImage, newImageResourceId, newX, newY, scaleX, scaleY));
}
if(event.getActionMasked() == MotionEvent.ACTION_POINTER_DOWN){
Log.i(TAG, "second pointer detected");
touchStateScale = true;
}
if (event.getAction() == MotionEvent.ACTION_UP) {
touchStateScale = false;
return false;
}
return true;
}
};
I am trying to do swipe from both side in Listview but now i only able to do from right side, but i want to do swipe from both left and right please can any one tell me how to do that.
private void swipe(int dis) {
if (dis > mMenuView.getWidth()) {
dis = mMenuView.getWidth();
}
if (dis < 0) {
dis = 0;
}
mContentView.layout(-dis, mContentView.getTop(), mContentView.getWidth() - dis, getMeasuredHeight());
mMenuView.layout(mContentView.getWidth() - dis, mMenuView.getTop(),
mContentView.getWidth() + mMenuView.getWidth() - dis,
mMenuView.getBottom());
}
/onSwipe Function/
public boolean onSwipe(MotionEvent event) {
mGestureDetector.onTouchEvent(event);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mDownX = (int) event.getX();
isFling = false;
break;
case MotionEvent.ACTION_MOVE:
// Log.i("byz", "downX = " + mDownX + ", moveX = " + event.getX());
int dis = (int) (mDownX - event.getX());
if (state == STATE_OPEN) {
dis += mMenuView.getWidth();
}
swipe(dis);
break;
case MotionEvent.ACTION_UP:
if (isFling
|| (mDownX - event.getX()) > (mMenuView.getWidth() / 1.5)) {
// open
smoothOpenMenu();
} else {
// close
smoothCloseMenu();
return false;
}
break;
}
return true;
}
Please go through the above code and suggest me some solution.
So i want to detect which direction the user moved his finger when touching the screen
Right now its working for 3 directions but the "up" movement does not get called.
This is my code:
#Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: {
// store the X value when the user's finger was pressed down
downXValue = event.getX();
downYValue = event.getY();
break;
}
case MotionEvent.ACTION_UP: {
// Get the X value when the user released his/her finger
float currentX = event.getX();
float currentY = event.getY();
//check if horizontal or vertical movement was bigger
if (Math.abs(downXValue - currentX) > Math.abs(downYValue)
- currentY) {
Log.e("motionevent", "x");
// going backwards: pushing stuff to the right
if (downXValue < currentX) {
Log.e("motionevent", "right");
}
// going forwards: pushing stuff to the left
if (downXValue > currentX) {
Log.e("motionevent", "left");
}
} else {
Log.e("motionevent", "y");
if (downYValue < currentY) {
Log.e("motionevent", "up");
}
if (downYValue > currentY) {
Log.e("motionevent", "down");
}
}
break;
}
}
return true;
}
Is there a Problem with checking for horizontal or vertical movement? because whenever i do an up movement, right or left gets called. down works fine.
You have error in your movement calculation. I have fixed it, its ok now.
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: {
// store the X value when the user's finger was pressed down
downXValue = event.getX();
downYValue = event.getY();
Log.v("", "= " + downYValue);
break;
}
case MotionEvent.ACTION_UP: {
// Get the X value when the user released his/her finger
float currentX = event.getX();
float currentY = event.getY();
// check if horizontal or vertical movement was bigger
if (Math.abs(downXValue - currentX) > Math.abs(downYValue
- currentY)) {
Log.v("", "x");
// going backwards: pushing stuff to the right
if (downXValue < currentX) {
Log.v("", "right");
}
// going forwards: pushing stuff to the left
if (downXValue > currentX) {
Log.v("", "left");
}
} else {
Log.v("", "y ");
if (downYValue < currentY) {
Log.v("", "down");
}
if (downYValue > currentY) {
Log.v("", "up");
}
}
break;
}
}
You can use GestureDetector.OnGestureListener interface which provides several methods to detect touch events: scroll, fling, etc.
Usage:
#Override
public boolean onTouchEvent(MotionEvent event) {
if (detector == null) {
detector = new GestureDetector(this);
}
return detector.onTouchEvent(event);
}
From now every events are recognized and passed to the specified method.