Scalegesturedetector Not Working For View Within Fragment Or Viewgroup Layout On Ics And Below
Solution 1:
From inspecting the ScaleGestureDetector
source code on grepcode, I see that Jellybean versions of ScaleGestureDetector
do not make use of getRawX()
and getRawY()
methods of the MotionEvent
. However, the earlier versions (Froyo, ICS etc) do make use of getRawX()
and getRawY()
for the purpose of slop calculation. This is where the problem is, because it means that the scale detector won't work if the target View
doesn't have its top left near 0,0.
I got the ScaleGestureDetector
to work on my custom ZoomView
, even with it being placed on the right or bottom, by simply doing this within onTouchEvent()
:
event.setLocation(event.getRawX(), event.getRawY());
mScaleDetector.onTouchEvent(event);
That causes adjustment of the MotionEvent
's internal offset variables such that the getX/Y
and getRawX/Y
methods now return exactly the same value. This prevents the slop calculation failing. The scale detector of course works with relative values and so it doesn't matter about the absolute values of X / Y. If you have further code that relies on the absolute values, you could do what I did to restore them after:
float originalY = event.getY();
float originalX = event.getX();
event.setLocation(event.getRawX(), event.getRawY());
mScaleDetector.onTouchEvent(event);
event.setLocation(originalX, originalY);
Furthermore, if I want to place my Fragment
that contains a MapView
on the bottom or right, I am already using a custom subclass of MapView
anyway and so I just added this:
public boolean onTouchEvent(MotionEvent event) {
// Work around required for ScaleGestureDetector.// Before calling the scale detector, perform a work-around that is needed for earlier APIs (I suspect// ICS and below, judging from inspection of ScaleGestureDetector) to make the MotionEvent give the // same values for getY / getRawY and getX / getRawX. Wildly different values, caused by the View// being nowhere near the screen origin (i.e. the View is on the right or the bottom) means the // detector doesn't work.
event.setLocation(event.getRawX() - getLeft(), event.getRawY() - getTop());
return super.onTouchEvent(event);
}
Now, my MapView
will pinch scale properly too, no matter where its Fragment
is placed. (By the way - totally OT to this question, but in case anyone is wondering, I placed a MapView
into a Fragment
successfully using the LocalActivityManager
solution as given on StackOverflow). EDIT: Actually, something is not 100% right: The map doesn't zoom around the center of the pinch gesture. I think it's to do with the ActionBar / notification bar height not being compensated for in the getTop()
.
Post a Comment for "Scalegesturedetector Not Working For View Within Fragment Or Viewgroup Layout On Ics And Below"