Alk
Alk

Reputation: 5567

Detecting Sloppy Clicks Android

I have an ImageView where I need to differentiate between a click and longclick as well as swipes. To do so I use the following code :

public boolean onTouch(View v, MotionEvent event) {
                                    Log.d(getClass().getName(), "touch event: " + event.toString());
                                    switch (event.getAction()) {

                                        case MotionEvent.ACTION_DOWN:
                                            x1 = event.getX();
                                            y1 = event.getY();
                                            t1 = System.currentTimeMillis();
                                            return true;
                                        case MotionEvent.ACTION_UP:
                                            x2 = event.getX();
                                            y2 = event.getY();
                                            t2 = System.currentTimeMillis();

                                            if (x1 == x2 && y1 == y2 && (t2 - t1) < LONG_PRESS_TIMEOUT) {
                                             //SHORT CLICK 
                                            }

The other if conditions identify hold if the time exceeeds the LONG_PRESS_TIMEOUT and swipes if the positions of the touch and release differ significantly. Anyway this works however the user needs to press and let go in the exact same point which makes it not able to identify touches which are a bit rough or sloppy, how could I alter the if condition to allow for these messy clicks but at the same time not set the offset to high so that swipes don't get mistaken as clicks.

Upvotes: 1

Views: 61

Answers (1)

Ryan
Ryan

Reputation: 1797

Define a radius of 'sloppy' clicks allowed which would effectively create a circle with the center coordinates of the initial click. Then validate that the release coordinates are within that circle.

To verify that the release coordinates are within that circle you would need to calculate the distance between the center of the circle and the point and validate that it's less than the radius. (See https://math.stackexchange.com/questions/198764/how-to-know-if-a-point-is-inside-a-circle for the math involved).

Pseudocode

bool isWithinCircle(int centerX, int centerY, int x, int y, double radius)
{
  var temp = pow(x - centerX, 2) + pow(y - centerY, 2);
  return sqrt(temp) < r;
}

then your if condition would be:

if (isWithinCircle(x1, y1, x2, y2, radius) && (t2 - t1) < LONG_PRESS_TIMEOUT) {
  //SHORT CLICK 
}

Upvotes: 1

Related Questions