简体   繁体   中英

Add Mapbox to Android View in Xamarin Forms Custom Renderer

I cannot figure out how to get a Mapbox map going in a custom view renderer on Android using Xamarin.Forms. It's driving me bonkers.

In my PCL, I have a map view.

public class MapView: View
{
    public MapView() { }
}

For iOS, the "getting started" help was close enough to get it working on iOS, like so:

[assembly: ExportRenderer (typeof(Shared.Mobile.MapView), typeof(MapViewRenderer))]
namespace Clients.iOS
{
    public class MapViewRenderer : ViewRenderer<Shared.Mobile.MapView, UIView>
    {
        protected override void OnElementChanged(ElementChangedEventArgs<Shared.Mobile.MapView> e)
        {
            base.OnElementChanged(e);

            if (e.NewElement == null)
            {
                return;
            }

            var uiView = new UIView(new CoreGraphics.CGRect(0, 0, 500, 700));
            SetNativeControl(uiView);

            var mapView = new MapView(Control.Bounds);
            mapView.SetCenterCoordinate(new CoreLocation.CLLocationCoordinate2D(40.81, -96.68), false);
            mapView.SetZoomLevel(11, false);

            mapView.AddAnnotation(new PointAnnotation
                {
                    Coordinate = new CoreLocation.CLLocationCoordinate2D(40.81, -96.68), 
                    Title = "Lincoln, NE",
                    Subtitle = "What-what"
                });

            uiView.AddSubview(mapView);
        }
    }
}

On the Android side, not so much. ( https://components.xamarin.com/gettingstarted/mapboxsdk ). They're putting in XML and an Activity of sorts, but my knowledge in mobile doesn't extend far from Xamarin.Forms at the moment, so I can't seem to bridge the gap between the two. My Android renderer looks like this:

public class MapViewRenderer : ViewRenderer<Shared.Mobile.MapView, Android.Views.View>
{     
    protected override void OnElementChanged(ElementChangedEventArgs<Shared.Mobile.MapView> e)
    {
        base.OnElementChanged(e);

        var view = new Android.Views.View(Context);
        SetNativeControl(view);  // NullReferenceException will be thrown if the native control is not set

        if (Control == null)
        {
            return;
        }

        var mapView = new MapView(Forms.Context, "thisismyaccesscode");
        mapView.CenterCoordinate = new LatLng(41.885, -87.679);
        mapView.ZoomLevel = 11;
        mapView.SetMinimumHeight(250);
        mapView.SetMinimumWidth(250);
        mapView.AddMarker(new MarkerOptions().SetPosition(new LatLng(40.81, -96.68)).SetTitle("Lincoln, NE"));

        view.AddSubview(mapView) // I wish this method existed
    }
}

My final call to AddSubview(mapView) is not in fact a method of the View class as it is the UIView class on iOS. Here's where I'm stuck. I cannot figure out how to display the MapView . Please help.

As you have already mentioned you can't call AddSubview as it is an iOS method.

On Android its the equivalent of AddView .

However - You are attempting to do this type of operation on a Android View object and not on a ViewGroup object, so its not possible.

First instead of doing:-

var view = new Android.Views.View(Context);

try instantiating the MapView directly such like:-

var view = new MapView(Context, "thisismyaccesscode");

Your SetNativeControl call on the view is fine.

I haven't tried the Mapbox component, so I'm unclear on the exact parameter types it is expecting in the code above.

Should that not work, however, then do something like the following:-

var view = new Android.Widget.FrameLayout(Context);

var mapView = new MapView(Forms.Context, "thisismyaccesscode");
mapView.CenterCoordinate = new LatLng(41.885, -87.679);
mapView.ZoomLevel = 11;
mapView.SetMinimumHeight(250);
mapView.SetMinimumWidth(250);
mapView.AddMarker(new MarkerOptions().SetPosition(new LatLng(40.81, -96.68)).SetTitle("Lincoln, NE"));

view.AddView(mapView);

SetNativeControl(view);

You will have to change your first line to the following also:-

public class MapViewRenderer : ViewRenderer<Shared.Mobile.MapView, Android.Widget.FrameLayout>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM