I have an overlay which I want to declutter based on the range from the map center.
I want to detect a change in the 开发者_JAVA百科current map center so that If a person is constantly moving the map around, panning to another area, I can declutter and repopulate data in the new area.
Is there a listener for this or am I going to have to create a thread to periodically check the map center?
I forget the name of it ..... you'll have to read the API documentation ..... but there are properties/methods of the MapActivity that define the boundries (in terms of lat / long) of the currently displayed map that you can use to determine what the center value would be. If the GPS is reporting the user is currently at XXX value, but they have panned the map in a direction that puts the calculated center YYYY away from where the GPS is reporting, then you can determine "how far away from center" the Map is now positioned. Use the Great Circle method, by the way, when doing the math.
I think something like this might work
When you first load the map get a projection and store the center GeoPoint of the middle of the view the map is being displayed on by using the MapView's Projection class
mapPosition = myMapView.getProjection().fromPixels(x,y)
Will return a GeoPoint related to x,y in this case x y needs to be he center of the MapView
Extend the MapView class
public myMapView extends Mapview { }
So you can override onDispatchDraw
In that method you can check if the zoom level has changed, if it has not then it's probably because the map is being panned, could be other reasons I suppose dependent on what you are doing but it's reasonable to think most redraws are pans if you exclude zooms
Compare the current projection GeoPoint of the center of the screen with the one you stored at startup. If it meets your distance critera perform your logic and update the mapPosition geopoint.
If I understand your question correctly something like that should work. Of course you could over ride other members of the extended class as well if you dont want to check on every redraw, the motion events could be used as well but you said you were having problems with those.
UPDATE:
You might be able to do this directly on MapView vs in a custom container but what I have done in the past is override dispatchTouchEvent on an extended container class that the mapview lives inside, in this case a Framelayout so
public class myFrameLayout extends FrameLayout {
Then inside of that I use something like this to track the state of the touch motions, I will reduce it to the minimum that should work, the "modes" are enums I created, where you would do logic is when the user lifts the finger at the bottom of the case statement
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_POINTER_UP: // Second Finger
case MotionEvent.ACTION_DOWN: // First finger
mode = GESTURE_MODE.PRE_DRAG;
break;
case MotionEvent.ACTION_MOVE:
if (GESTURE_MODE.PRE_DRAG == mode) // Pan
mode = GESTURE_MODE.DRAG;
else
{
}
break;
case MotionEvent.ACTION_POINTER_DOWN:
mode = GESTURE_MODE.MULTI_TOUCH;
break;
case MotionEvent.ACTION_UP: // All fingers removed
if (GESTURE_MODE.DRAG == mode)
{
// DO YOUR PANNING MOVED FAR LOGIC HERE
}
mode = GESTURE_MODE.NONE;
break;
}
return super.dispatchTouchEvent(event);
}
精彩评论