在Xamarin.Android中显示地图,OnMapReady从未调用过

时间:2016-08-22 14:56:24

标签: google-maps xamarin xamarin.android android-fragmentactivity

我正在尝试在Xamarin.Android项目中加载一个简单的谷歌地图。我有自己的渲染器,所以我不能将它添加到Activity或通过xaml或布局。(我也没有片段)。您可以在此处找到我的代码,主要问题是:OnMapReady()从未调用过。

    public class AndroidMap:FragmentActivity
    {
        private GoogleMap GMap;
        public AndroidMap()
        {
            SetUpMap();
        }
        private void SetUpMap()
        {
            var mapFragment = FragmentManager.FindFragmentByTag("map") as MapFragment;
            if (mapFragment != null)
                return;
            var mapOptions = new GoogleMapOptions()
              .InvokeMapType(GoogleMap.MapTypeHybrid)
              .InvokeZoomControlsEnabled(enabled: true)
              .InvokeCompassEnabled(enabled: true);


            var fragTx = FragmentManager.BeginTransaction();
            mapFragment = MapFragment.NewInstance(mapOptions);
            fragTx.Add(mapFragment, "map");
            //if (!IsFinishing && !IsDestroyed) 
            //    fragTx.Commit();  
            var mapReadyCallback = new MyOnMapReady();

            mapReadyCallback.MapReady += (sender, args) =>
            {
                GMap = ((MyOnMapReady)sender).Map;//receive the Map object when completed
            };

            mapFragment.GetMapAsync(mapReadyCallback);        
            while (GMap == null)
                Thread.Sleep(10);
            MainView = mapFragment.View;
        }           
    }

    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);//send the Map object back when completed
        }
    }

我很感激,如果有人知道它为什么总是空的。

2 个答案:

答案 0 :(得分:0)

您没有提交片段交易。

假设你在清单中分配了com.google.android.geo.API_KEY,这样的话可以让你走上正轨:

public class AndroidMap : Java.Lang.Object, IOnMapReadyCallback
{
    readonly FragmentActivity activity;
    public MapFragment mapFragment { get; private set; }
    public GoogleMap Map { get; private set; }

    public AndroidMap(FragmentActivity activity)
    {
        this.activity = activity;
        SetUpMap();
    }

    public void OnMapReady(GoogleMap googleMap)
    {
        Map = googleMap;
        // Do something with your GoogleMap / MapFragment
    }

    void SetUpMap()
    {
        var mapOptions = new GoogleMapOptions()
          .InvokeMapType(GoogleMap.MapTypeHybrid)
          .InvokeZoomControlsEnabled(enabled: true)
          .InvokeCompassEnabled(enabled: true);
        mapFragment = MapFragment.NewInstance(mapOptions);

        var fragmentTransaction = activity.FragmentManager.BeginTransaction();
        fragmentTransaction.Add(mapFragment, "map");
        fragmentTransaction.Commit();

        using (var handler = new Handler(Looper.MainLooper))
            handler.Post(() =>
            {
                mapFragment.GetMapAsync(this);
            });
    }
}

通过传入FragmentActivity实例创建实例:

map = new AndroidMap(this);

答案 1 :(得分:0)

我在Fragment内使用了MapView,并遵循了我使用的以下代码以及我的Markers等。希望有人能从此代码中获得帮助,因为我自己无法直接获得帮助,因此我将MapView的本机Java代码转换为Xamarin Android C#。

我的片段代码:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
  <TextView
      android:id="@+id/arbitraryView"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="@string/Title" />
  <com.google.android.gms.maps.MapView
        android:id="@+id/mapView"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"/>
</LinearLayout>

然后,我的片段文件代码如下:

public class PropertyMapView : Fragment, IOnMapReadyCallback
{

    private GoogleMap googleMap;
    private MapView mapView;
    private bool mapsSupported = true;

    static readonly LatLng Location_Xamarin = new LatLng(37.80, -122.40);
    static readonly LatLng Location_NewYork = new LatLng(40.77, -73.98);
    static readonly LatLng Location_Chicago = new LatLng(41.88, -87.63);
    static readonly LatLng Location_Dallas = new LatLng(32.90, -97.03);
    static readonly LatLng Location_Author = new LatLng(47.855334, 12.184079);

    public override void OnActivityCreated(Bundle savedInstanceState)
    {

        base.OnCreate(savedInstanceState);
        try
        {
            MapsInitializer.Initialize(Activity);
        }
        catch (GooglePlayServicesNotAvailableException e)
        {
            mapsSupported = false;
        }

        if (mapView != null)
        {
            mapView.OnCreate(savedInstanceState);
        }

        //initialize Map
        mapView.GetMapAsync(this);
    }

    public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {
        //return base.OnCreateView(inflater, container, savedInstanceState);
        var view = inflater.Inflate(Resource.Layout.PropMapView, container, false);
        mapView = view.FindViewById<MapView>(Resource.Id.mapView);

        return view;
    }

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

        googleMap.MapType = GoogleMap.MapTypeNormal;
        googleMap.MyLocationEnabled = true;
        googleMap.UiSettings.CompassEnabled = false;
        googleMap.UiSettings.MyLocationButtonEnabled = true;
        googleMap.UiSettings.ZoomControlsEnabled = true;

        //googleMap.UiSettings.SetAllGesturesEnabled(false);

        googleMap.AddMarker(new MarkerOptions()
            .SetPosition(Location_NewYork));

        googleMap.AddMarker(new MarkerOptions()
            .SetPosition(Location_Xamarin)
            .SetTitle("Xamarin HQ")
            .SetSnippet("Where the magic happens")
            .SetIcon(BitmapDescriptorFactory.DefaultMarker(BitmapDescriptorFactory.HueOrange)));

        Marker chicagoMarker = googleMap.AddMarker(new MarkerOptions()
            .SetPosition(Location_Chicago)
            .SetTitle("Chicago")
            .Draggable(true)
            .SetIcon(BitmapDescriptorFactory.DefaultMarker(BitmapDescriptorFactory.HueYellow)));

        Marker dallasMarker = googleMap.AddMarker(new MarkerOptions()
            .SetPosition(Location_Dallas)
            .SetTitle("Dallas")
            .SetSnippet("Go Cowboys!")
            .InfoWindowAnchor(1, 0)
            .SetIcon(BitmapDescriptorFactory.DefaultMarker(BitmapDescriptorFactory.HueBlue)));

        googleMap.MarkerClick += delegate (object sender, GoogleMap.MarkerClickEventArgs e) {
            if (e.Marker.Equals(dallasMarker))
            {
                dallasMarker.Flat = !dallasMarker.Flat;
                dallasMarker.ShowInfoWindow();
            }
            else
            {
                // Execute default behavior for other markers.
                e.Handled = false;
            }
        };

        googleMap.InfoWindowClick += (sender, e) =>
        {
            if (e.Marker.Id == chicagoMarker.Id)
            {
                e.Marker.SetIcon(BitmapDescriptorFactory.DefaultMarker(BitmapDescriptorFactory.HueRose));
            }
        };

        googleMap.MapClick += (sender, e) =>
        {
            if (!chicagoMarker.IsInfoWindowShown)
            {
                chicagoMarker.SetIcon(BitmapDescriptorFactory.DefaultMarker(BitmapDescriptorFactory.HueYellow));
            }
        };

        googleMap.AddMarker(new MarkerOptions()
            .SetPosition(Location_Author)
            .SetTitle("Author")
            .SetSnippet("Author Home")
            .SetIcon(BitmapDescriptorFactory.DefaultMarker(BitmapDescriptorFactory.HueViolet)));

        googleMap.MapLongClick += (sender, e) =>
            googleMap.AnimateCamera(CameraUpdateFactory.ZoomOut(), 1000, null);

        // Center on Xamarin HQ
        CameraUpdate update = CameraUpdateFactory.NewLatLngZoom(Location_Author, googleMap.MaxZoomLevel);
        googleMap.MoveCamera(update);
    }


    public override void OnSaveInstanceState(Bundle outState)
    {
        base.OnSaveInstanceState(outState);
        mapView.OnSaveInstanceState(outState);
    }

    public override void OnResume()
    {
        base.OnResume();
        mapView.OnResume();
    }

    public override void OnPause()
    {
        base.OnPause();
        mapView.OnPause();
    }

    public override void OnDestroy()
    {
        base.OnDestroy();
        mapView.OnDestroy();
    }

    public override void OnLowMemory()
    {
        base.OnLowMemory();
        mapView.OnLowMemory();
    }

}