title: How to preserve/rebind event listeners on MapFragment after rotating the device (portrait / landscape)?
body: <p>I am developing an Android app with Xamarin (version 7.1). It displays as map and draws PolyLines, doing so in <code>OnCameraIdle()</code>.</p>
  
  <p>The <code>MapFragment</code> is generated programmatically in <code>OnCreate</code>. I am fetching the <code>GoogleMap</code> in <code>OnResume</code> via <code>GetMapAsync</code> and binding the listeners in <code>OnMapReady</code>.<br>
  They work fine, but only in the beginning. As soon as the device is rotated (portrait -> landscape OR vice versa), the camera movement does not trigger the listeners any more.<br>
  The map works, however - I (the user) can still move the camera just fine. I (the app) just can't work with it anymore.</p>
  
  <p>This is the bare code, only map creation and handling. Everything else (actual drawing) is removed:</p>
  
  <pre><code>public class MapActivity : Activity, IOnMapReadyCallback, 
      GoogleMap.IOnCameraIdleListener, GoogleMap.IOnCameraMoveStartedListener
  {
      private GoogleMap _map;
      private MapFragment _mapFragment;
  
      private void InitializeMap()
      {
          _mapFragment = MapFragment.NewInstance();
          var tx = FragmentManager.BeginTransaction();
          tx.Add(Resource.Id.map_placeholder, _mapFragment);
          tx.Commit();
      }
  
      private void SetMapListeners()
      {
          Log.Debug("MyApp/ Map", "SetMapListeners");
          _map.SetOnCameraIdleListener(this);
          _map.SetOnCameraMoveStartedListener(this);
      }
  
      /* Activity */
  
      protected override void OnCreate(Bundle savedInstanceState)
      {
          base.OnCreate(savedInstanceState);
          Log.Debug("MyApp / Map", "OnCreate");
          SetContentView(Resource.Layout.Map);
          InitializeMap();
      }
  
      protected override void OnStart()
      {
          base.OnStart();
          Log.Debug("MyApp / Map", "OnStart");
      }
  
      protected override void OnResume()
      {
          base.OnResume();
          if (_map == null)
              _mapFragment.GetMapAsync(this);
          Log.Debug("MyApp / Map", "OnResume");
      }
  
      protected override void OnPause()
      {
          base.OnPause();
          Log.Debug("MyApp / Map", "OnPause");
      }
  
      protected override void OnStop()
      {
          base.OnStop();
          Log.Debug("MyApp / Map", "OnStop");
      }
  
      protected override void OnDestroy()
      {
          base.OnStop();
          Log.Debug("MyApp/ Map", "OnDestroy");
      }
  
  
      /* IOnMapReadyCallback */   
  
      public void OnMapReady(GoogleMap googleMap)
      {
          Log.Debug("MyApp / Map", "Map is ready!");
          _map = googleMap;       
          SetMapListeners();
      }
  
  
      /* IOnCameraIdleListener */
  
      public void OnCameraIdle()
      {
          Log.Debug("MyApp / Map", "Camera is idle.");
          // Drawing routine is called here
      }
  
  
      /* IOnCameraMoveStartedListener */
  
      public void OnCameraMoveStarted(int reason)
      {
          Log.Debug("MyApp / Map", "Camera move started.");
      }
  }
  </code></pre>
  
  <p>As you can see in the following log excerpt, the listeners do work in the beginning, but once the device is rotated (at least) once, they are gone.<br>
  I also tried calling <code>SetMapListeners</code> only once in the lifecycle, the first time <code>OnMapReady</code> is called, but that did not change anything.</p>
  
  <pre><code>04-03 20:29:06.486 D/MyApp / Map( 7446): OnCreate
  04-03 20:29:06.688 I/Google Maps Android API( 7446): Google Play services client version: 10084000
  04-03 20:29:06.695 I/Google Maps Android API( 7446): Google Play services package version: 10298438
  04-03 20:29:07.394 D/MyApp / Map( 7446): OnStart
  04-03 20:29:07.399 D/MyApp / Map( 7446): OnResume
  04-03 20:29:07.432 D/MyApp / Map( 7446): Map is ready!
  04-03 20:29:07.438 D/MyApp / Map( 7446): SetMapListeners
  04-03 20:29:07.568 D/MyApp / Map( 7446): Camera is idle.
  04-03 20:29:09.231 D/MyApp / Map( 7446): Camera move started.
  04-03 20:29:09.590 D/MyApp / Map( 7446): Camera is idle.
  04-03 20:29:12.350 D/MyApp / Map( 7446): Camera move started.
  04-03 20:29:12.751 D/MyApp / Map( 7446): Camera is idle.
  
  ## Listeners are responding, now rotating the device.
  
  04-03 20:29:15.503 D/MyApp / Map( 7446): OnPause
  04-03 20:29:15.508 D/MyApp / Map( 7446): OnStop
  04-03 20:29:15.572 D/MyApp / Map( 7446): OnDestroy
  04-03 20:29:15.595 I/Google Maps Android API( 7446): Google Play services package version: 10298438
  04-03 20:29:15.596 D/MyApp / Map( 7446): OnCreate
  04-03 20:29:15.628 I/Google Maps Android API( 7446): Google Play services package version: 10298438
  04-03 20:29:15.655 D/MyApp / Map( 7446): OnStart
  04-03 20:29:15.655 D/MyApp / Map( 7446): OnResume
  04-03 20:29:15.690 D/MyApp / Map( 7446): Map is ready!
  04-03 20:29:15.691 D/MyApp / Map( 7446): SetMapListeners
  
  ## Map is rotated, camera position was preserved. 
  ## Now moving the camera, but no listeners are responding.
  
  04-03 20:29:24.436 D/MyApp / Map( 7446): OnPause
  04-03 20:29:31.288 D/MyApp / Map( 7446): OnStop
  04-03 20:29:31.359 D/MyApp / Map( 7446): OnDestroy
  </code></pre>
  
  <p>The interesting thing here for me is that when I switch back to the previous activity and open the map once again, it starts fresh and works again. However, as you see in the log, while rotating the device, the activity is also destroyed and freshly created. As far as I know, the fragment is not, so maybe that's hint. I don't know.</p>
  
  <p>I also tried removing the listeners in <code>OnDestroy</code> (by setting <code>null</code>), but that, too, did not change anything.</p>
  
  <p>Have you got any idea what I might be doing wrong?</p>