简体   繁体   中英

System.ObjectDisposedException: Cannot access a disposed object. Object name: 'Android.Gms.Maps.GoogleMap using renders on google map on xamarin forms

I am using the following code for my map. When the nativeMap.Clear() on CustomRenderer.cs is executed, System.ObjectDisposedException: Cannot access a disposed object. Object name: 'Android.Gms.Maps.GoogleMap error has occured.

Anyone please help me.

MapPage.xaml:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:App33.CustomControls"
             x:Class="App33.Forms.MapPage">
    <ContentPage.Content>
        <StackLayout>
            <local:CustomMap x:Name="customMap" Grid.Row="0" Grid.Column="0" Margin="0" MapType="Street" HasZoomEnabled="True" IsShowingUser="True" WidthRequest="300"  HeightRequest="600" VerticalOptions="FillAndExpand" />
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

MapPage.xaml.cs:

using App33.CustomControls;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Xamarin.Forms;
using Xamarin.Forms.Maps;
using Xamarin.Forms.Xaml;

namespace App33.Forms
{
    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class MapPage : ContentPage
    {
        public MapPage ()
        {
            InitializeComponent ();

            customMap.MoveToRegion(MapSpan.FromCenterAndRadius(new Position(13.008677, 80.208194), Xamarin.Forms.Maps.Distance.FromMiles(6)));

            #region Pin Location
            var farmPin = new CustomPin
            {
                Type = PinType.Place,
                Position = new Position(13.008677, 80.208194),
                Label = "Farm Field",
                Id = "IdBlueFarmField",
                Uri = "IdBlueFarmField",
                farmId = 1,
                FarmFieldInde = "FarmField",
                ElevatorName = "Elevator",
                Icon= "Green"
            };
            customMap.Pins.Add(farmPin);
            customMap.CustomPins.Add(farmPin);
            #endregion

        }
    }
}

CustomControls/CustomMap.cs:

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;
using Xamarin.Forms;
using Xamarin.Forms.Maps;

namespace App33.CustomControls
{
    public class CustomMap:Map
    {
        public static readonly BindableProperty RouteCoordinatesProperty =
        BindableProperty.Create<CustomMap, ObservableCollection<CustomPosition>>(p => p.RouteCoordinates, new ObservableCollection<CustomPosition>());


        public static readonly BindableProperty CustomPinsProperty =
      BindableProperty.Create<CustomMap, ObservableCollection<CustomPin>>(p => p.CustomPins, new ObservableCollection<CustomPin>());

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

        public ObservableCollection<CustomPin> CustomPins
        {
            get { return (ObservableCollection<CustomPin>)GetValue(CustomPinsProperty); }
            set { SetValue(CustomPinsProperty, value); }
        }
        public CustomMap()
        {
            RouteCoordinates = new ObservableCollection<CustomPosition>();
        }
        public CustomMap(MapSpan region) : base(region)
        {

        }
    }
}

CustomControls/CustomPin.cs:

using System;
using System.Collections.Generic;
using System.Text;
using Xamarin.Forms.Maps;

namespace App33.CustomControls
{
    public class CustomPin : Pin
    {
        public string Uri { get; set; }
        public string truckerId { get; set; }
        public int farmId { get; set; }
        public string FarmFieldInde { get; set; }
        public string ElevatorName { get; set; }
        public string Icon { get; set; }
        public double PreviousPinValueLatitude { get; set; }
        public double PreviousPinValueLongitude { get; set; }

        public float PreviousBearing;
        public float Bearing;
        public Position PreviousPosition { get; set; }

    }
}

CustomControls/CustomPosition.cs:

using System;
using System.Collections.Generic;
using System.Text;
using Xamarin.Forms.Maps;

namespace App33.CustomControls
{
    public class CustomPosition
    {
        public CustomPosition(double lat, double lng)
        {
            Latitude = lat;
            Longitude = lng;
        }
        public double Latitude { get; set; }
        public double Longitude { get; set; }
        public int farmId { get; set; }

        public string ElevatorName { get; set; }
    }
}

App33.Android/CustomMapRenderer.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Xamarin.Forms;
using Xamarin.Forms.Maps.Android;
using Xamarin.Forms.Maps;
using Xamarin.Forms.Platform.Android;
using Android.Gms.Maps;
using Android.Gms.Maps.Model;
using System.ComponentModel;
using System.Collections.ObjectModel;

using App33.CustomControls;
using App33.Droid;


[assembly: ExportRenderer(typeof(CustomMap), typeof(CustomMapRenderer))]
namespace App33.Droid
{
    public class CustomMapRenderer: MapRenderer
    {
        ObservableCollection<Position> routeCoordinates;
        ObservableCollection<Polyline> PolylineBuffer = new ObservableCollection<Polyline>();
        ObservableCollection<CustomPin> customPins;
        GoogleMap nativeMap;
        Polyline polyline;
        ObservableCollection<Marker> markerR = new ObservableCollection<Marker>();
        private CustomMap Maps;

        public CustomMapRenderer() : base()
        {

        }

        protected override void OnElementChanged(ElementChangedEventArgs<Map> e)
        {
            base.OnElementChanged(e);
            try
            {
                if (e.OldElement != null)
                {
                    var nativeMap = Control as MapView;
                    if (nativeMap != null)
                    {
                    }
                }

                if (e.NewElement != null)
                {
                    Maps = (CustomMap)e.NewElement;
                    customPins = Maps.CustomPins;
                    Control.GetMapAsync(this);
                    if (customPins != null)
                    {
                        Maps.CustomPins.CollectionChanged += CustomPins_CollectionChanged;
                    }
                }
            }
            catch (Exception ex)
            {

            }
        }

        protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            base.OnElementPropertyChanged(sender, e);
            try
            {
                if (Element == null || Control == null)
                    return;
                Maps = (CustomMap)sender;
                if (e.PropertyName == CustomMap.CustomPinsProperty.PropertyName || e.PropertyName == "VisibleRegion")
                {
                    if (Maps.CustomPins != null)
                    {
                        customPins = Maps.CustomPins;
                    }
                }
            }
            catch (Exception ex)
            {

            }
        }

        private void CustomPins_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
            customPins = (ObservableCollection<CustomPin>)sender;
            UpdateMarker();
        }

        private void UpdateMarker()
        {
            try
            {
                if (nativeMap != null)
                {
                    nativeMap.Clear();
                }
                foreach (var custompin in customPins)
                {
                    var marker = new MarkerOptions();
                    marker.SetPosition(new LatLng(custompin.Position.Latitude, custompin.Position.Longitude));
                    marker.SetTitle(custompin.Label);
                    if (custompin.Icon == "Green")
                    {
                        marker.SetIcon(BitmapDescriptorFactory.FromResource(Resource.Drawable.green));
                    }
                }
            }
            catch (Exception ex)
            {

            }
        }

        protected override void OnMapReady(GoogleMap map)
        {
            //base.OnMapReady(map);
            nativeMap = map;
            nativeMap.MyLocationEnabled = false;
            nativeMap.UiSettings.MyLocationButtonEnabled = false;
            nativeMap.UiSettings.CompassEnabled = false;
            nativeMap.UiSettings.RotateGesturesEnabled = false;
        }
    }
}

In OnElementChanged , you have a local variable, var nativeMap , meaning the global variable GoogleMap nativeMap is never assigned to.

Here's the updated code for OnElementChanged

protected override void OnElementChanged(ElementChangedEventArgs<Map> e)
{
    base.OnElementChanged(e);
    try
    {
        if (e.OldElement != null)
        {
            nativeMap = Control as MapView;
            if (nativeMap != null)
            {
            }
        }

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