I have a class CustomCanvasView
extending View
, and I've implemented clicking, dragging, and pinch-zooming for the class. Now I want to implement long clicks.
From what I've read in various posts, everyone has a different way of doing this, but the general consensus seems to be that I should use either an OnLongClickListener
or a GestureDetector
. However, I need the exact coordinates of the long click, and I'm worried that these approaches may not play nicely with what I've got working in my onTouch()
method.
So which approach is really best for these specific needs?
UPDATE
So, I decided to measure the time manually by setting startTime = System.nanoTime();
in the ACTION_DOWN
case of my onTouch(...)
event, and then finding
estimatedTime = System.nanoTime() - startTime;
seconds = (double) estimatedTime / 1000000000.0;
in theACTION_UP
case, and testing to see if this value exceeds 1. This worked, and so I wanted to add haptic feedback.
Since all of this is being handled inside a class (not an activity) I decided to pass the information about the click to the associated activity, and have it vibrate the device using a Vibrator
in the case of a long click. This also works, but, since the information is not passed until after the long click has finished, that is when the vibration occurs.
In apps I've used the haptic feedback nicely occurs as your finger is down so that you can tell that you've passed the time threshold for a long click before you lift your finger. Is there any way to have that occur here without reworking the entire logic of my app? I.e., can I vibrate the phone from within an inner class?
UPDATE
I figured out how to make the haptic feedback work better than it was. It still isn't perfect, but here is how I did it.
Rather then checking the value of estimatedTime
in the ACTION_UP
case of onTouch(...)
, I set a boolean timerStarted
equal to true
in the ACTION_DOWN
case and then in the beginning of onTouch(...)
just check if the timer was started, and if so inspect the value of estimatedTime
. If It exceeds my threshold value then I tell the associated activity to provide haptic feedback. I also set mode = LONG_CLICK
so I have this information in the ACTION_UP
case.
You just need to make sure that you set timerStarted = false
in all the right places (i.e. if you determine that the event is a zoom event, a drag event, or a click event) and you should be good.
Thanks!
For custom long touch detect you can use TimerTask
,
Below is sample code
public Timer mTIMERForLongTouch;
Handler mHandler = new Handler(){};
int mTIMEForLongTouch=0;
float longTouchX, longTouchY;
if(event.getAction()==MotionEvent.ACTION_DOWN)
{
// longTouchX & longTouchY is x-y coordinate of long touch
longTouchX = event.getX();
longTouchY = event.getY();
mTIMERForLongTouch = new Timer();
mTIMERForLongTouch.schedule(new TimerTask() {
@Override
public void run() {
mTIMEForLongTouch+= 100;
if(mTIMEForLongTouch>1500)
{
mHandler.post(new Runnable()
{
public void run()
{
Toast.makeText(context, "Long Touch", Toast.LENGTH_SHORT).show();
mTIMERForLongTouch.cancel();
mTIMEForLongTouch=0;
}
});
}
}
}, 0,100);
}
else if(event.getAction()==MotionEvent.ACTION_UP)
{
mTIMEForLongTouch=0;
mTIMERForLongTouch.cancel();
}