Why does my custom infowindow
not 'inflate' after a configuration change?
I have an app that places a marker on a map using MarkerManager
, and sets a custom info-window using setInfoWindowAdapter
.
After loading the app and clicking on the marker, the info-window correctly displays my custom layout.
However, after rotating the app so that the configuration changes, selecting the marker no longer displays the custom info-window, and instead only displays the generic 'title'.
What have I missed in all the hours of reading and tutorials that means I'm not correctly implementing this?
Here is a stripped-down version of my app to replicate the issue
MapsActivity
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {
private GoogleMap mMap;
MarkerManager.Collection mMarkerManagerCollection;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
if(savedInstanceState == null){
mapFragment.setRetainInstance(true); // maintains the map fragment on orientation changes
}
}
@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
MarkerManager mMarkerManager = new MarkerManager(mMap);
mMap.setInfoWindowAdapter(mMarkerManager);
mMarkerManagerCollection = mMarkerManager.newCollection("myMarker");
mMarkerManagerCollection.setOnInfoWindowAdapter(new GoogleMap.InfoWindowAdapter(){
@Override
public View getInfoWindow(Marker marker) {
return null;
}
@Override
public View getInfoContents(Marker marker) {
View v = getLayoutInflater().inflate(R.layout.info_window, null);
TextView tv = (TextView) v.findViewById(R.id.myTv);
tv.setText("hello world, this is my marker");
return v;
}
});
// Add a marker in Sydney and move the camera
LatLng sydney = new LatLng(-34, 151);
MarkerOptions options = new MarkerOptions()
.position(sydney)
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED))
.flat(true)
.title("Marker in Sydney");
Marker marker = mMarkerManagerCollection.addMarker(options);
marker.setTag("test marker");
mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));
}
}
info_window.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:layout_width="93dp"
android:layout_height="96dp"
android:id="@+id/rect_load"
android:padding="2dp"
android:src="@mipmap/ic_launcher"
/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/myTv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="myText"/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
Gradle
compile 'com.android.support:appcompat-v7:25.0.0'
compile 'com.google.android.gms:play-services:9.8.0'
compile 'com.google.maps.android:android-maps-utils:0.4'
compile 'com.google.android.gms:play-services:9.8.0'
The problem is that you are creating and populating a new MarkerManager
on each onMapReady
call. As onMapReady
gets called when the orientation changes but you are not removing old markers, the map has two markers on the same position.
When you click the marker after the orientation changes, the old marker is triggered and you see the default behaviour (show title). If you click the marker again you will see your info window.
One possible solution can be calling mMap.clear();
on the onMapReady
before adding markers.