不刷新自定义渲染器Xamarin表单映射

时间:2016-07-24 07:14:44

标签: google-maps xamarin xamarin.android xamarin.forms custom-renderer

我使用自定义标记创建了一个带有实时位置更新的地图。但是在向地图添加新引脚后,它不应用自定义渲染器。如果我在地图上放大或缩小,则应用该自定义渲染标记。这是我的代码。

此代码位于Xamarin.Droid项目中

     public class CustomMapRenderer : MapRenderer, IOnMapReadyCallback, GoogleMap.IInfoWindowAdapter
{

    GoogleMap map;
    List<Position> routeCoordinates;
    List<CustomPin> customPins;
    Action<CustomPin> onInfoWindowClicked;


    public void OnMapReady(GoogleMap googleMap)
    {
        map = googleMap;

        //map.InfoWindowClick += OnInfoWindowClick;
        map.SetInfoWindowAdapter(this);

        var polylineOptions = new PolylineOptions();
        polylineOptions.InvokeColor(Android.Graphics.Color.Blue);

        foreach (var position in routeCoordinates)
        {
            polylineOptions.Add(new LatLng(position.Latitude, position.Longitude));
        }

        map.AddPolyline(polylineOptions);

    }

    protected override void OnElementChanged(Xamarin.Forms.Platform.Android.ElementChangedEventArgs<Xamarin.Forms.View> e)
    {
        base.OnElementChanged(e);

        if (e.OldElement != null)
        {
            map.InfoWindowClick -= OnInfoWindowClick;
            // Unsubscribe
        }

        if (e.NewElement != null)
        {

            var formsMap = (CustomMap)e.NewElement;

            routeCoordinates = formsMap.RouteCoordinates;
            customPins = formsMap.CustomPins;
            onInfoWindowClicked = formsMap.OnInfoWindowClicked;
            ((Android.Gms.Maps.MapView)Control).GetMapAsync(this);
        }
    }

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

        if (map != null)
        {
            map.Clear();

            foreach (var pin in customPins)
            {
                var marker = new MarkerOptions();
                marker.SetPosition(new LatLng(pin.Pin.Position.Latitude, pin.Pin.Position.Longitude));
                marker.SetTitle(pin.Id.ToString());
                marker.SetSnippet(pin.Pin.Address);

                if(pin.UserType == global::Common.Models.UserType.Driver)
                {
                    marker.SetIcon(BitmapDescriptorFactory.FromResource(Resource.Drawable.car));
                }

                else if (pin.UserType == global::Common.Models.UserType.Rider)
                {
                    marker.SetIcon(BitmapDescriptorFactory.FromResource(Resource.Drawable.person));
                }

                map.AddMarker(marker);
            }

        }
    }

    void OnInfoWindowClick(object sender, GoogleMap.InfoWindowClickEventArgs e)
    {
        onInfoWindowClicked(GetCustomPin(e.Marker));
    }

    private CustomPin GetCustomPin(Marker marker)
    {
        return customPins.Find(x => x.Id.ToString() ==marker.Title.ToString());
    }

    public Android.Views.View GetInfoContents(Marker marker)
    {
        var inflater = Android.App.Application.Context.GetSystemService(Context.LayoutInflaterService) as Android.Views.LayoutInflater;
        if (inflater != null)
        {
            Android.Views.View view;

            var customPin = GetCustomPin(marker);
            if (customPin == null)
            {
                throw new Exception("Custom pin not found");
            }

            view = inflater.Inflate(Resource.Layout.MapInfoWindow, null);

            var infoImage = view.FindViewById<ImageView>(Resource.Id.markerInfoImage);
            var infoTitle = view.FindViewById<TextView>(Resource.Id.markerInfoTitle);
            var infoSummary = view.FindViewById<TextView>(Resource.Id.markerInfoSummary);



            System.IO.Stream ims = Context.Assets.Open(customPin.Image);

            // load image as Drawable
            Drawable d = Drawable.CreateFromStream(ims, null);

            // set image to ImageView
            infoImage.SetImageDrawable(d);


            //File file = new File(customPin.Image);
            //var image  = Android.Net.Uri.FromFile(file);
            //var resource=ResourceManager.GetDrawableByName("driverLogActive_icon.png");
            //infoImage.SetImageResource(resource);
            //infoImag = customPin.Title;

            infoTitle.Text = customPin.Title;

            infoSummary.Text = customPin.MobileNo;

            return view;
        }
        return null;
    }

    public Android.Views.View GetInfoWindow(Marker marker)
    {
        return null;
    }
}

此代码位于Xamarin.Forms项目中

    public class CustomPin
{
    public Pin Pin { get; set; }
    public Guid Id { get; set; }
    public string Title { get; set; }
    public string MobileNo { get; set; }
    public string Image { get; set; }
    public string UserName { get; set; }
    public UserType UserType { get; set; }
}

public class CustomMap : Map
{
    public static readonly BindableProperty RouteCoordinatesProperty = BindableProperty.Create(nameof(RouteCoordinates), typeof(List<Position>), typeof(CustomMap), new List<Position>(), BindingMode.TwoWay);
    public static readonly BindableProperty CustomPinsProperty = BindableProperty.Create(nameof(CustomPins), typeof(List<CustomPin>), typeof(CustomMap), new List<CustomPin>(), BindingMode.TwoWay);



    public List<CustomPin> CustomPins
    {
        get { return (List<CustomPin>)GetValue(CustomPinsProperty); }
        set { SetValue(CustomPinsProperty, value); }
    }

    public List<Position> RouteCoordinates
    {
        get { return (List<Position>)GetValue(RouteCoordinatesProperty); }
        set { SetValue(RouteCoordinatesProperty, value); }
    }

    public Action<CustomPin> OnInfoWindowClicked;

    public CustomMap()
    {
        RouteCoordinates = new List<Position>();
        CustomPins = new List<CustomPin>();
    }
}

这就是我在Xamrin.Fomrs项目中使用自定义地图渲染图钉的方式

    private void RenderPin(string longitudeCoordinate, string latitudeCoordinate,bool canMoveToLoacation, string lable,UserType userType,string mobileNo,string image,string userName)
    {
        double latitude = 0;
        double longitude = 0;

        double.TryParse(latitudeCoordinate, out latitude);
        double.TryParse(longitudeCoordinate, out longitude);

        var position = new Position(latitude, longitude);

        var pin = new CustomPin
        {
            Pin = new Pin
            {
                Type = PinType.Place,
                Position = position,
                Label = lable,
            },
            Title = lable,
            UserType = userType,
            MobileNo = "Mobile No:" + mobileNo,
            Image = "profile_images/" + image,
            UserName = userName,
            Id = Guid.NewGuid()
        };


        map.CustomPins.Add(pin);
        map.Pins.Add(pin.Pin);
        if (canMoveToLoacation)
        {
            map.MoveToRegion(MapSpan.FromCenterAndRadius(new Position(latitude, longitude), Distance.FromKilometers(2)));
        }
    }

1 个答案:

答案 0 :(得分:0)

如果您安装Xamarin.Forms.Maps预发布版(2.3.5.255-pre5),现在可以覆盖CreateMarker()中的MapRenderer方法。它更加优雅,它解决了这个问题,在地图创建后添加时,引脚没有更新。