SimpleOnGestureListener onSingleTapUp never called

I created a custom component with both onTouchListener and a gesture detector. I put the custom component in the MainActivity XML file, which also has onTouchEvent and a gesture detector. I want to detect single taps on a user component and press MainActivity for a long time, but it seems that touch listeners are interacting somehow and single taps are never detected.

MainActivity.java:

public class MainActivity extends ActionBarActivity { private GestureDetector detector; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); detector = new GestureDetector(this, new LongPressDetector()); } @Override public boolean onTouchEvent(MotionEvent event) { detector.onTouchEvent(event); int action = event.getActionMasked(); switch (action){ case MotionEvent.ACTION_DOWN:{ Log.d("TouchEvent", "Action_Down at MainActivity.java"); break; } } return super.onTouchEvent(event); } private class LongPressDetector extends GestureDetector.SimpleOnGestureListener{ @Override public boolean onDown(MotionEvent e) { Log.d("TouchEvent", "onDown at MainActivity.java"); return super.onDown(e); } @Override public void onLongPress(MotionEvent e) { Log.d("TouchEvent", "onLongPress at MainActivity.java"); super.onLongPress(e); } } } 

CustomView.java:

 public class CustomView extends RelativeLayout { private GestureDetector detector; public CustomView(Context context, AttributeSet attrs) { super(context, attrs); init(context); } private void init(Context c){ LayoutInflater layoutInflater = (LayoutInflater) c.getSystemService(Context.LAYOUT_INFLATER_SERVICE); layoutInflater.inflate(R.layout.customview, this); detector = new GestureDetector(c, new TapDetector()); this.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { detector.onTouchEvent(event); int action = event.getActionMasked(); switch (action){ case MotionEvent.ACTION_DOWN:{ Log.d("TouchEvent", "Action_Down at CustomView.java"); break; } } return false; } }); } private class TapDetector extends GestureDetector.SimpleOnGestureListener{ @Override public boolean onDown(MotionEvent e) { Log.d("TouchEvent", "onDown at CustomView.java"); return super.onDown(e); } @Override public boolean onSingleTapUp(MotionEvent e) { Log.d("TouchEvent", "onSingleTapUp at CustomView.java"); return super.onSingleTapUp(e); } } } 
+5
source share
3 answers

If you are going to respond to a click, you also need to return true from onDown, the default value will return false (I assume here).

At least for me, I did not get onSingleTapUp for my code until I made sure that onDown returned true.

  @Override public boolean onDown(MotionEvent e) { return true; } 

I have seen other frameworks where up events are only delivered if down events are received, so I assumed that this is what happens here.

+12
source

no need to guess (@alexndr) !!! watch sources

if u extends the call to GestureDetector.SimpleOnGestureListener for super.onDown (event)

  public boolean onDown(MotionEvent e) { return false; } 

will return false, but if u implements a gesture detector listener, then there is no super!

 public class GestureDetector { /** * The listener that is used to notify when gestures occur. * If you want to listen for all the different gestures then implement * this interface. If you only want to listen for a subset it might * be easier to extend {@link SimpleOnGestureListener}. */ public interface OnGestureListener { /** * Notified when a tap occurs with the down {@link MotionEvent} * that triggered it. This will be triggered immediately for * every down event. All other events should be preceded by this. * * @param e The down motion event. */ boolean onDown(MotionEvent e); 

ps. the rule is simple:

if the EVENT NEEDS RETURN TRUE if NOT RETURN FALSE

+3
source

You just need to return true in onTouchEvent(MotionEvent event) .

Somewhat:

 @Override public boolean onTouchEvent(MotionEvent event) { detector.onTouchEvent(event); int action = event.getActionMasked(); switch (action){ case MotionEvent.ACTION_DOWN:{ Log.d("TouchEvent", "Action_Down at MainActivity.java"); break; } } return true; } 
0
source

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


All Articles