IOnMapReadyCallback usage in a non-activity class?

SachinAgrawalSachinAgrawal USUniversity ✭✭

Hi, I have a Xamarin forms map and I have written a Custom Renderer for the Android map inheriting from ViewRenderer. The map is working fine, but then I upgraded the GooglePlay Services and now the "mapview.Map" way of initializing the GoogleMap is obsolete. Any recommendation on how to achieve this using the mapView.GetAsync() without implementing IOnMapReadyCallback in my MainActivity?

Posts

  • CheesebaronCheesebaron DKInsider, University mod

    I have a blog post on this matter here: http://blog.ostebaronen.dk/2015/01/changing-from-map-property-to.html

    Basically as you see in the post, you can implement the interface IOnMapReadyCallback in its own class, rather than on your Activity. You just need to inherit that class from Java.Lang.Object which will provide the Dispose and Handler implementations.

    private class MyOnMapReady : Java.Lang.Object, IOnMapReadyCallback
    {
      public GoogleMap Map { get; private set; }
    
      public event EventHandler MapReady;
    
      public void OnMapReady(GoogleMap googleMap)
      {
        Map = googleMap;
        var handler = MapReady;
        if (handler != null)
          handler(this, EventArgs.Empty);
      }
    }
    

    You can ofcourse also change the EventHandler to an Action instead if you like or pass the map in the event. Loads of possibilities here.

  • SachinAgrawalSachinAgrawal USUniversity ✭✭

    Hi @Cheesebaron Thanks for getting back to me. Unfortunately this approach is not working for me. I always get the googlemap instance back as NULL. So here is what I have. I created a new class as suggested above. Now my usage is in the "OnElementChanged" of the customrenderer is below:
    protected override void OnElementChanged(ElementChangedEventArgs e)
    {
    try
    {
    base.OnElementChanged(e);

                mapView = new MapView(this.Context);
                Bundle bundle = new Bundle();
                if(mapView != null)
                {
                    mapView.OnCreate(bundle);
                    SetUpMapIfNeeded();
    
                    MapsInitializer.Initialize(this.Context);
                    mapView.OnResume();
                    SetUpMapIfNeeded();
                    //remove the view from the parent container before refreshing/reloading the map page
                    ViewGroup parent = (ViewGroup)mapView.Parent;
                    if (parent != null)
                    {
                        parent.RemoveView(mapView);
                    }
                    if (_googleMap != null)
                    {
                        _googleMap.MapType = GoogleMap.MapTypeNormal;
                        _googleMap.UiSettings.RotateGesturesEnabled = false;
                        _googleMap.CameraChange += Map_CameraChange;
                        HydrateRouteData();
    
                    }
                    SetNativeControl(mapView);
                }                
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
    
        private void SetUpMapIfNeeded()
        {
              //if(null != _googleMap || _gettingMap) return;
            if (null != _googleMap) return;
              var mapReadyCallback = new GoogleMapOnReady();
              mapReadyCallback.MapReady += (sender, args) =>
              {
                  _gettingMap = false;
              };
    
              _gettingMap = true;
              mapView.GetMapAsync(mapReadyCallback); 
        }
    
  • Hi @SachinAgrawal , I have the same problem. It's my code but the map is always null. Have you found any solution for that?

    public class AndroidMapView : MapView
    {
    private GoogleMap gMap;
    private MapView mapView;
    bool _gettingMap = false;

        public AndroidMapView() : base(Renderer.Context)
        {
            SetUpMapIfNeeded();
            if (gMap != null)
            {
                gMap.MapType = GoogleMap.MapTypeNormal;
                gMap.UiSettings.RotateGesturesEnabled = false;
            }
        }
    
        private void SetUpMapIfNeeded()
        {
            if (null != gMap) return;
            var mapReadyCallback = new MyOnMapReady();
            mapReadyCallback.MapReady += (sender, args) =>
            {
                _gettingMap = false;
            };
    
            _gettingMap = true;
            GetMapAsync(mapReadyCallback);
        }
    }
    
    public class MyOnMapReady : Java.Lang.Object, IOnMapReadyCallback
    {
        public GoogleMap Map { get; private set; }
    
        public event EventHandler MapReady;
    
        public void OnMapReady(GoogleMap googleMap)
        {
            Map = googleMap;
            var handler = MapReady;
            if (handler != null)
                handler(this, EventArgs.Empty);
        }
    }
    
Sign In or Register to comment.