How To Change GoogleMap V2 Camera Center?
Solution 1:
You should use Map Padding, namely the setPadding(int left, int top, int right, int bottom)
method:
...
public void onMapReady(GoogleMap googleMap) {
mGoogleMap = googleMap;
mGoogleMap.setPadding(0, dHeight, 0, 0);
...
}
...
where dHeight = Target_pos.y - cam_pos.y
. And you should move compass button, like in this answer of Vignon with some changes for drawing compass outside of clipping region:
try {
final ViewGroup parent = (ViewGroup) mMapFragment.getView().findViewWithTag("GoogleMapMyLocationButton").getParent();
parent.post(new Runnable() {
@Override
public void run() {
try {
Resources r = getResources();
//convert our dp margin into pixels
int marginPixels = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 20, r.getDisplayMetrics());
// Get the map compass view
View mapCompass = parent.getChildAt(4);
View v = mapCompass;
while (v.getParent() != null && v.getParent() instanceof ViewGroup) {
ViewGroup viewGroup = (ViewGroup) v.getParent();
viewGroup.setClipChildren(false);
viewGroup.setClipToPadding(false);
v = viewGroup;
}
// create layoutParams, giving it our wanted width and height(important, by default the width is "match parent")
RelativeLayout.LayoutParams rlp = new RelativeLayout.LayoutParams(mapCompass.getHeight(),mapCompass.getHeight());
// position on top right
rlp.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
rlp.addRule(RelativeLayout.ALIGN_PARENT_TOP, 0);
rlp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, 0);
rlp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, 0);
//give compass margin
rlp.setMargins(marginPixels, dHeight, marginPixels, marginPixels);
mapCompass.setLayoutParams(rlp);
} catch (Exception ex) {
ex.printStackTrace();
}
}
});
} catch (Exception ex) {
ex.printStackTrace();
}
Also you can try that dirty solution (see the picture)
is to scale height of MapFragment
(MapView
) to dHeight
more then visible area (screen height), where:
dHeight = (int) (k * MapFragment.height)
where k = Target_pos.y / cam_pos.y
. In that case map center moved exactly to your desired point (but bottom (white on picture) part of map will not be visible). Also you should move up zoom controls, because by default it also at the bottom of map and will not be visible too. You can do this like in this answer. But remember, that as per the Google Maps APIs Terms of Service, your application must not remove or obscure the Google logo or copyright notices.
Seems the right solution is to create custom view, which extends MapFragment
or MapView
, e.g. like in that answer and do all your every location offset calculate magic inside it.
Solution 2:
Finally I've came to the solution!!
The padding solution is good for a static map but when you want to do continuance animation on the map like in navigation, the padding causes to un expected movement in turns, especially when the map tilts and zoomed!!
The MapView size solution is the right choice here as it simply push the center of the map.
The problem with that approach is that it also pushes down the zoom control and most important the Google logo which must be visible.
So, you have to explicitly set the the zoom control and Google logo bottom margin back so they will be visible again! This without putting any padding to the map view itself.
Alternatively you can set the controls and the logo position to different corners if it's ok for your need, I've decided just to set their margins.
Here is my code:
final ViewTreeObserver observer = mapView.getViewTreeObserver();
observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
mainParentLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this);
int parentHeight = ((ViewGroup)mapView.getParent()).getHeight() - toolbar.getHeight();
int mapHeight = parentHeight + parentHeight/2;
mapView.getLayoutParams().height = mapHeight;
int margin = mapHeight - parentHeight + 2*((int)(getResources().getDimension(R.dimen.small_image) + getResources().getDimension(R.dimen.small_pargin)));
Log.i(TAG, "onGlobalLayout: parent height: " + parentHeight + ", map new height: " + mapHeight + ", margin: " + margin);
setMapControlsMargin(margin);
}
});
This code, waits for the map view to be shown, then it calculate the map parent view height (in my case a ConstraintLayout) then it set the map height to be parentHeight * 1.5. This will push the camera center down! Then, set the margin the Google logo and zoom controls.
private void setMapControlsMargin(final int margin){
try {
//Find the Zoom controls parent
final ViewGroup parent = (ViewGroup) mapView.findViewWithTag("GoogleMapMyLocationButton").getParent();
//Find the Google logo parent view group
final ViewGroup googleLogo = (ViewGroup) mapView.findViewWithTag("GoogleWatermark").getParent();
Log.i(TAG, "setMapControlsMargin: found Google logo " + (googleLogo != null));
//Set the margin for the Google logo
if (googleLogo != null) {
FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) googleLogo.getLayoutParams();
layoutParams.bottomMargin = margin;
}
parent.post(() -> {
try {
View zoomControls = parent.getChildAt(2); //Zoom controls
ViewGroup.LayoutParams layoutParams1 = zoomControls.getLayoutParams();
//Read the zoom controls original margin, this will be added to the offset margin
int origBotMargin = ((RelativeLayout.LayoutParams) layoutParams1).bottomMargin;
int origRightMargin = ((RelativeLayout.LayoutParams) layoutParams1).rightMargin;
// create layoutParams, giving it our wanted width and height(important, by default the width is "match parent")
RelativeLayout.LayoutParams rlp = new RelativeLayout.LayoutParams(zoomControls.getWidth(),zoomControls.getHeight());
// position on bottom right
rlp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, RelativeLayout.TRUE);
rlp.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, RelativeLayout.TRUE);
//set the new margin
rlp.setMargins(0, 0, origRightMargin, origBotMargin + margin);
zoomControls.setLayoutParams(rlp);
} catch (Exception ex) {
ex.printStackTrace();
}
});
} catch (Exception ex) {
ex.printStackTrace();
}
}
I was helped this post to move the Google logo.
Post a Comment for "How To Change GoogleMap V2 Camera Center?"