I have both an onClickListener
and an onFling
(using GestureDetector
).
If I click on the button the onClickListener
fires.
If I fling on the body of the screen then onFling
fires.
However if I start the fling from the button, then neither fire.
Layout as follows:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/myButton"
android:layout_margin="50dp"
android:layout_height="100dp"
android:layout_width="match_parent"
android:text="Button"/>
</LinearLayout>
And the code looks like:
public class myLayout extends Activity implements GestureDetector.OnGestureListener {
private GestureDetector gDetector;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.myLayout);
gDetector = new GestureDetector(getBaseContext(), this);
findViewById(R.id.myButton).setOnClickListener(button_OnClickListener);
}
final View.OnClickListener button_OnClickListener = new View.OnClickListener() {
public void onClick(final View buttonView) {
Toast.makeText(getApplicationContext(), "button pressed", Toast.LENGTH_LONG).show();
}
};
@Override
public boolean onDown(MotionEvent motionEvent) {
return true;
}
@Override
public void onShowPress(MotionEvent motionEvent) {
}
@Override
public boolean onSingleTapUp(MotionEvent motionEvent) {
return false;
}
@Override
public boolean onScroll(MotionEvent motionEvent, MotionEvent motionEvent2, float v, float v2) {
return false;
}
@Override
public void onLongPress(MotionEvent motionEvent) {
}
@Override
public boolean onFling(MotionEvent start, MotionEvent finish, float v, float v2) {
if (start.getRawY() < finish.getRawY()) {
Toast.makeText(getApplicationContext(), "Fling detected", Toast.LENGTH_LONG).show();
}
return false;
}
@Override
public boolean onTouchEvent(MotionEvent me) {
Log.i("Touch", "onTouchEvent");
return gDetector.onTouchEvent(me);
}
}
How can I get the onFling
to be run first?
I have looked at other posts for this (e.g. onClick blocking onFling) but not found a suitable answer.
You should try using onInterceptTouchEvent()
(or, maybe dispatchTouchEvent()
, at this point I'm not sure which will suit better) of the Button
's parent (or something even higher in hierarchy) to decide whether to route the touch to the button or the gesture detector.
If the MotionEvent
's coordinates belong to the Button
's rect and ACTION_DOWN
is followed by ACTION_UP
shortly, it's a click and should be routed to the Button
, but if you receive ACTION_MOVE
and the movement continues to the extent where you know it's a swipe - it should be handled by gesture detector.
UPD Here's an answer which explains the technique https://stackoverflow.com/a/3834952/375929