わかりました。デフォルトでは、マーカーをクリックすると、マーカーは地図の中央に配置されます。問題は、レイアウトから膨らんだ高い infoView があり、マップの境界外に表示されることです。ピンを水平方向に中央に配置し、マップの中央の下に配置して、infoWindow を表示するにはどうすればよいですか。
4 に答える
だから私はこの解決策に行き着きました。それは魅力のように機能します。アニメーションの後に infoWindow を開いています。
int zoom = (int)map.getCameraPosition().zoom
CameraUpdate cu = CameraUpdateFactory.newLatLngZoom(new
LatLng(arg0.getPosition().latitude + (double)90/Math.pow(2, zoom),
arg0.getPosition().longitude), zoom);
map.animateCamera(cu,500,null);
GoogleMaps uses Web Mercator which extremely distorts the data in high latitudes because it essentially maps our planet to a square. Thanks to this, the further you are from equator, the bigger error you introduce to some simplified calculations.
We will instead let Android deal with those for us ;)
In the following text mGoogleMap
is your GoogleMap
. We will set a
onMarkerClickListener
in which we open the InfoWindow
(as in the default implementation of onMarkerClickListener) and then instead of
centering on the marker itself, we recalculate the camera center position according to the GoogleMap projection.
mGoogleMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
@Override
public boolean onMarkerClick(Marker marker) {
// Calculate required horizontal shift for current screen density
final int dX = getResources().getDimensionPixelSize(R.dimen.map_dx);
// Calculate required vertical shift for current screen density
final int dY = getResources().getDimensionPixelSize(R.dimen.map_dy);
final Projection projection = mGoogleMap.getProjection();
final Point markerPoint = projection.toScreenLocation(
marker.getPosition()
);
// Shift the point we will use to center the map
markerPoint.offset(dX, dY);
final LatLng newLatLng = projection.fromScreenLocation(markerPoint);
// Buttery smooth camera swoop :)
mGoogleMap.animateCamera(CameraUpdateFactory.newLatLng(newLatLng));
// Show the info window (as the overloaded method would)
marker.showInfoWindow();
return true; // Consume the event since it was dealt with
}
});
animateCamera()
moves the camera to the calculated position smoothly, you can jump to the new position with moveCamera()
.
We also need to add the two dimensions, map_dx
and map_dy
, to the resources:
<resources>
<!-- Where to shift the map center when user taps on marker -->
<dimen name="map_dx">10dp</dimen>
<dimen name="map_dy">-100dp</dimen>
</resources>
And we're done, this method (unlike some others) work well all over the map, even close to the Earth's poles.
infoWindow のアダプタでこれを試してください:
@Override
public View getInfoWindow(Marker marker) {
View infoWindowLayout = (View) inflater.inflate(R.layout.my_info_window_layout, null);
int width = display.getWidth() (I put here a "*2/3" too to not fill the whole screen, but this is your choice);
LinearLayout infoWindowSubLayout = (LinearLayout) infoWindowLayout.findViewById(R.id.myInfoWindowSubLayout);
android.widget.LinearLayout.LayoutParams lp = new android.widget.LinearLayout.LayoutParams(width, LayoutParams.MATCH_PARENT);
infoWindowSubLayout.setLayoutParams(lp);
return infoWindowLayout;
}
私の場合、これのレイアウトファイルは次のようになります。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/myInfoWindowLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/..."
android:orientation="horizontal"
... >
<LinearLayout
android:id="@+id/myInfoWindowSubLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:orientation="horizontal"
...>
<LinearLayout
android:layout_width="0px"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center_vertical"
android:orientation="vertical" >
CONTENT HERE
</LinearLayout>
CONTENT HERE TOO
</LinearLayout>
</LinearLayout>
まあ、これは私にとってはうまくいきます、自由に書き直してください