How to accept onSingleTapUp () internally and accept onFling () in appearance?

I have a view that spans the entire screen (say, ParentView ) and an internal view of a ChildView child that spans only part of it. I want to make ChildView to respond to onSingleTapUp() , and ParentView to onFling() . I am trying to do this by adding one SimpleOnGestureListener to ChildView and one SimpleOnGestureListener to ParentView .

To accept onSingleTapUp() from ChildView , its onDown() listener must return true. But as soon as I do this, the listener attached to the ParentView no longer hears any motion events, as it is perceived by the ChildView listener. Even if ChildView onFling() returns false, events are not sent to the ParentView .

How can I make the parent view listener catch the fling gesture while the listener is listening to the child view receiver?

I don’t think that any source code is needed to explain the situation, but here is the snippet that my ChildView listener ChildView .

 ChildView.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View view, MotionEvent motionEvent) { return singleTapGestureDetector.onTouchEvent(motionEvent); } }); 

A workaround could be to use both ParentView and ChildView listeners to handle onFling() , but only the ChildView descriptor-listener onSingleTapUp() , but in this case the failure cannot happen through ChildView (for example, start outside the child and then end inside child), I suppose.

+4
source share
1 answer

I do not like my decision, but I found a way to do it. Hopefully someone else will post a better answer in the future, or at least my workaround is useful to someone else.

As I described in the question, the problem is how the gesture listener works. To view the onSingleTapUp() child, you return true on onDown() . But once you do this, the next series of events will not go to the parent view even after your child view onTouch() announces that it is no longer interested in the event. If you strongly call the parent onTouch() in the child onTouch() when its gesture pointer returns false, yes, the parent onFling () will be output, but the first argument to MouseEvent will be NULL since it was consumed by the onTouch() child view.

Something must be missing for me, because it seems like a very simple gesture detection script. In any case, I could not find a way to do this in a reasonable way.

So, my workaround is to create a TouchListenerService as a singleton.

Both the child view and the parent view have this line :

 view.setOnTouchListener(TouchListenerService.Instance()); 

and TouchListenerService starts as follows:

 public class TouchListenerService extends GestureDetector.SimpleOnGestureListener implements View.OnTouchListener { // some code to implement singleton public SingleTapUpHandler SingleTapUpHandler; public FlingHandler FlingHandler; private View _touchingView; GestureDetector gestureDetector; @Override public boolean onTouch(View view, MotionEvent motionEvent) { if (gestureDetector == null) gestureDetector = new GestureDetector(_touchListenerService); _touchingView = view; boolean result = gestureDetector.onTouchEvent(motionEvent); _touchingView = null; return result; } // and some more code 

Since it is the same event handler, the parent view captures the onFling() event successfully, and the child view can set SingleTapUpHandler to handle the click event.

+2
source

Source: https://habr.com/ru/post/1434417/


All Articles