I want to capture an event when the user slides his finger from one view to another.
I was able to capture the movement of the finger via the following code
view1.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
Toast.makeText(MainActivity.this, "touch listener", Toast.LENGTH_SHORT).show();
Log.e("touch event", "triggered");
return true;
}
});
But it only works when the user starts the finger movement from the same view (i.e View1). I want to capture the finger movement in View1 even when the user enters from View2. at least the first event when the user enters View1 would be enough. but the touch event doesn't trigger at all when I move a finger in View1 which comes from View2.
CodePudding user response:
Every time the location, pressure, or size of the currently selected touch contact changes, a new onTouchEvent() function is called with an ACTION MOVE event. All of these events are saved in the MotionEvent parameter of onTouchEvent, as explained in Detect common gestures ().
Detecting touch events frequently relies more on movement than on simple contact since finger-based touch isn't always the most exact method of engagement. Android contains the concept of "touch slop" to assist apps in differentiating between movement-based gestures (such as a swipe) and non-movement gestures (such as a single tap). The term "touch slop" describes the number of pixels a user's touch might stray before it is recognized as a movement-based gesture.
public class MainActivity extends Activity {
private static final String DEBUG_TAG = "Velocity";
...
private VelocityTracker mVelocityTracker = null;
@Override
public boolean onTouchEvent(MotionEvent event) {
int index = event.getActionIndex();
int action = event.getActionMasked();
int pointerId = event.getPointerId(index);
switch(action) {
case MotionEvent.ACTION_DOWN:
if(mVelocityTracker == null) {
// Retrieve a new VelocityTracker object to watch the
// velocity of a motion.
mVelocityTracker = VelocityTracker.obtain();
}
else {
// Reset the velocity tracker back to its initial state.
mVelocityTracker.clear();
}
// Add a user's movement to the tracker.
mVelocityTracker.addMovement(event);
break;
case MotionEvent.ACTION_MOVE:
mVelocityTracker.addMovement(event);
// When you want to determine the velocity, call
// computeCurrentVelocity(). Then call getXVelocity()
// and getYVelocity() to retrieve the velocity for each pointer ID.
mVelocityTracker.computeCurrentVelocity(1000);
// Log velocity of pixels per second
// Best practice to use VelocityTrackerCompat where possible.
Log.d("", "X velocity: " mVelocityTracker.getXVelocity(pointerId));
Log.d("", "Y velocity: " mVelocityTracker.getYVelocity(pointerId));
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
// Return a VelocityTracker object back to be re-used by others.
mVelocityTracker.recycle();
break;
}
return true;
}
}
CodePudding user response:
final View view1 = findViewById(R.id.view1);
final Rect rectOfView1 = new Rect();
view1.post(() -> view1.getGlobalVisibleRect(rectOfView1)); // populating the rectOfView1 after the view1 is inflated
final View view2 = findViewById(R.id.view2);
view2.setOnTouchListener((v, event) -> {
if (rectOfView1.contains((int) event.getRawX(), (int) event.getRawY())) {
Log.d("view1 event", "triggered");
return true;
}
Log.d("view2 event", "triggered");
return true;
});