0

I was wondering if it is possible to have Views sitting on top of each other and separate listeners for them. Specifically, I have two views that are exactly sitting on top of each other and are the exact same dimensions, and I'm trying to implement a motion event OnTouchListener for view_one and an OnLongPressListener for view_two. However, the OnTouchListener on view_one seems to block the OnLongClickListener for view_one.

The basic goal of the code is to have multiple touch interactions doing different things:

  1. Short click does one thing
  2. Long press does another
  3. Touch drag and release in vertical direction does another thing
  4. Touch-drag in horizontal another

Etc, as many different things as possible.

Maybe I should just have one View that is for touching rather than two, and there is a way to separate out the touches and motion events. I know how to separate short and long press events, but the motion event messes things up.

I'm sure there is a much better way to do this. Any hints or suggestions are much appreciated. Is there a way to put limits on the length of slide motion and touch duration that help determine which action to take?

Peter O.
  • 32,158
  • 14
  • 82
  • 96
jdods
  • 323
  • 7
  • 18
  • Thanks for the edits, I'm new to this, so I'll work on the formatting more next time. Are comments like this are considered off topic and not allowed? – jdods Mar 29 '13 at 18:16
  • if the 2 views are of the same dimensions, why do you need to detect touches on both instead of just consuming the touches on the top view. a long press on view 1 is the same as a long press on view 2, if they are of the exact same dimensions and location... – ab11 Mar 29 '13 at 18:40
  • Yes, I think you are correct... I was just going about this all wrong. kyle's solution below solved my problem. – jdods Mar 29 '13 at 21:06

1 Answers1

0

To answer the first part of your question - if the touch listener is consuming the event before it reaches view_two (the underneath view), it may be because you are consuming the touch event in your onTouchListener.

//Returns true if the listener has consumed the event, false otherwise.
public abstract boolean onTouch (View v, MotionEvent event)

Are you always returning false in this method? If not, there are events that probably won't get propagated to the next view in the hierarchy.

As for your second question - yes, you certainly can create an onTouchListener to handle all of these events. Here's an example that does short and long press (independent of how much movement there is):

private MotionEvent downEvent;

public abstract boolean onTouch (View v, MotionEvent event){
    if (downEvent == null && event.getAction == MotionEvent.ACTION_DOWN){
        downEvent = event;
        return false;
    }


    if (event.getAction == MotionEvent.ACTION_UP){
        if (event.getDownTime() > LONG_PRESS_THRESHOLD){
            ... do something ...
        } else if (event.getDownTime() > SHORT_PRESS_THRESHOLD){
            ... do something else ...
        } 
    }
}

As you can imagine, it will only take a bit more effort lines to determine if the delta X / delta Y between your down event and current event meets the threshold you determine for events 3 and 4.

klmprt
  • 651
  • 6
  • 7
  • Ok, that makes alot of sense. With some more googling and a lot of work I was able to get this implemented. Thanks!!! I think there are a couple of typos above: getAction(). I had to add the parentheses to get it to work. Also, getDownTime() gave me some trouble as that gives the system up time that the down event occurred, so I had to implement a getEventTime() to get the time that the up event occurred and then take the difference to compare to whatever threshold times I declare. – jdods Mar 29 '13 at 21:01