Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Xamarin.Forms.Maps 2.3.4 custom MapRenderer disables everything

My problem occurs after I updated Xamarin.Forms and Xamarin.Forms.Maps to the new version (2.3.4).

After that I also updated all google play services in Android project (and a lot of libraries that I hate).

The main problem is that I have a custom MapRenderer for custom pins, in iOS and UWP works fine, but in Android version this custom MapRenderer brokes all the Map. Any property change or method call seems to be ignored.

For example I have a button to toggle the map type (Hybrid or Street) and that action never changes it. I also noticed (according this tutorial: https://developer.xamarin.com/guides/xamarin-forms/application-fundamentals/custom-renderer/map/customized-pin/) that the property "VisibleRegion" never changes so the following code never executes:

protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        base.OnElementPropertyChanged(sender, e);

        if (e.PropertyName.Equals("VisibleRegion") && !_isDrawn)
        {
            // Do something with your custom map
        }
    }

Inside that if i used to populate my custom pins (like the tutorial above) and now my Map is always empty.

Now i populate my map inside the IOnMapReadyCallback and it works fine, but the I still have the bindings problem.

If I ignore the custom MapRendered (removing the assembly line) all the bindings starts working fine but my map now have the old pins and all customization is gone (obviously).

In the PCL I have things like MyMap.MoveToRegion(...) and MyMap.MapType = _currentType; but those instructions only works if a don't use a custom MapRenderer.

My custom MapRenderer is almost the same as the tutorial above.

The custom Map is created with C# and not with XAML, it doesn't have any XAML binding but any property change or method call like the MoveToRegion or MapType is totally ignored if i'm using the MapRenderer.

Any help?

Thanks

like image 470
Isaac Ojeda Avatar asked Apr 12 '17 16:04

Isaac Ojeda


1 Answers

I already found the solution.

Looking at the source code, MapRenderer already implements IOnMapReadyCallback and if you remove the implementation in the custom MapRendered, everything starts working again (but with no customization).

MapRenderer saves the google map instance in the property NativeMap (also exists the property Map that is the Xamarin forms map instance) so we don't need to implement IOnMapReadyCallback any more. I think we need to be careful in the use of NativeMap because at the begining it could be null.

In the method I mentioned before now i do this:

    protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        base.OnElementPropertyChanged(sender, e);

        if (e.PropertyName.Equals("VisibleRegion") && !_isDrawn)
        {
            PopulateMap();
            OnGoogleMapReady();
        }
    }

and the code I had in OnMapReady now goes inside OnGoogleMapReady():

    private void OnGoogleMapReady()
    {
        if (_mapReady) return;

        NativeMap.InfoWindowClick += OnInfoWindowClick;
        NativeMap.SetInfoWindowAdapter(this);

        _mapReady = true;
    }

I also added this in OnElementChanged to remove any registered delegate in NativeMap

        if (e.OldElement != null)
        {
            NativeMap.InfoWindowClick -= OnInfoWindowClick;
        }

At the moment exists a Pull Request that implements OnMapReady as virtual method, so we can override it in our implementation and now be sure when NativeMap is not null, but for that we need to wait for a next release.

You can read more here -> https://forums.xamarin.com/discussion/92565/android-ionmapreadycallback-forms-2-3-4

like image 192
Isaac Ojeda Avatar answered Nov 08 '22 16:11

Isaac Ojeda