我正在尝试使用Xamarin表单制作谷歌地图,这些图钉正确显示并放大到用户身上。它会在页面开始时显示初始地图,但在移动或缩放时,如果放大的话,地图不会改变并变为网格。我可以在网格和所有内容上看到我的引脚,但我希望地图与引脚一起加载。
public partial class IssueMap2 : ContentPage
{
public UIIssueVM Issue { get; set; }
public GeoLocation Location { get; set; }
public bool AllowPinMovment { get; set; }
private ExtendedMap.ExtendedMap map;
public Xamarin.Forms.Maps.Position OrgIssueLocation { get; set; }
bool IsGettingLocation = false;
bool bMapCtrlReady = false;
IGeolocator Locator;
public IssueMap2(UIIssueVM Issue, GeoLocation location)
{
AllowPinMovment = false;
this.Issue = Issue;
this.Location = location;
Title = "Map";
OrgIssueLocation = new Xamarin.Forms.Maps.Position(Issue.Latitude, Issue.Longitude);
Locator = CrossGeolocator.Current;
if (Locator.DesiredAccuracy != 100)
Locator.DesiredAccuracy = 100;
if (Device.RuntimePlatform != Device.WinPhone)
{
InitializeComponent();
map = new ExtendedMap.ExtendedMap()
{
IsShowingUser = true,
HeightRequest = 100,
WidthRequest = 960,
VerticalOptions = LayoutOptions.FillAndExpand
};
map.LongTap += OnMapLongTap;
map.Ready += MapCtrlReady;
slMap.Children.Add(map);
}
}
public void MapCtrlReady(object sender, EventArgs args)
{
bMapCtrlReady = true;
}
public void OnMapLongTap(object sender, ExtendedMap.TapEventArgs args)
{
if (AllowPinMovment == false)
return;
if (Issue == null)
return;
var pos = args.Position;
// Update Issue
Issue.Latitude = pos.Latitude;
Issue.Longitude = pos.Longitude;
Issue.Changed = true;
// Update Pin
map.Pins.Clear();
AddPin(pos, Issue.Title, Issue.Description);
}
protected void AddPin(Xamarin.Forms.Maps.Position pos, String Title, String Desc)
{
// MAP pin does not like it if labels are empty
if (Title.Length == 0)
Title = "-";
if (Desc.Length == 0)
Desc = "-";
var pin = new Pin
{
Type = PinType.Place,
Position = pos,
Label = Title,
Address = Desc
};
map.Pins.Add(pin);
}
protected override void OnAppearing()
{
if (Device.RuntimePlatform == Device.WinPhone)
{
aActIndicator.IsRunning = false;
aActIndicator.IsVisible = false;
if (Issue.IsNew == false)
{
var position = new Xamarin.Forms.Maps.Position(Issue.Latitude, Issue.Longitude);
AddPin(position, Issue.Title, Issue.Description);
MoveToPinLocation();
}
else // Issue is new
{
// Move to main location
map.MoveToRegion(MapSpan.FromCenterAndRadius(new Xamarin.Forms.Maps.Position(Location.Latitude, Location.Longitude), Distance.FromMiles(1)));
// Get current location for new item
OnGetLocation();
}
}
}
protected override async void OnDisappearing()
{
if (Locator.IsListening)
{
await Locator.StopListeningAsync();
}
// Map controller crashes sometimes if we are to quick with exiting
await Task.Delay(500);
while (bMapCtrlReady == false)
{
await Task.Delay(500);
}
}
void OnButtonCenter(object sender, EventArgs args)
{
MoveToPinLocation();
}
void MoveToPinLocation()
{
double KmDistace = 0.5;
if (Issue != null)
{
map.MoveToRegion(MapSpan.FromCenterAndRadius(new Xamarin.Forms.Maps.Position(Issue.Latitude, Issue.Longitude), Distance.FromKilometers(KmDistace)));
}
else
map.MoveToRegion(MapSpan.FromCenterAndRadius(new Xamarin.Forms.Maps.Position(Location.Latitude, Location.Longitude), Distance.FromKilometers(KmDistace)));
}
void OnButtonMainLocation(object sender, EventArgs args)
{
double KmDistace = 0.5;
map.MoveToRegion(MapSpan.FromCenterAndRadius(new Xamarin.Forms.Maps.Position(Location.Latitude, Location.Longitude), Distance.FromKilometers(KmDistace)));
}
void OnButtonGetLocation(object sender, EventArgs args)
{
OnGetLocation();
}
async void OnGetLocation()
{
if (IsGettingLocation == true)
return; // already getting location
try
{
if (Locator.IsListening == true)
{
await Locator.StopListeningAsync();
}
if (Locator.IsGeolocationAvailable == false)
{
lbPosText.Text = "GeoLocation is not available.";
this.ForceLayout();
return;
}
if (Locator.IsGeolocationEnabled == false)
{
lbPosText.Text = "GeoLocation is not enabled.";
this.ForceLayout();
return;
}
IsGettingLocation = true;
IsBusy = true;
slCommands.IsVisible = false;
aActIndicator.IsVisible = true;
aActIndicator.IsRunning = true;
lbPosText.Text = "Searching for GPS location...";
this.ForceLayout();
TimeSpan timeSpan = TimeSpan.FromTicks(120 * 1000);
var position = await Locator.GetPositionAsync(timeSpan);
// Update Issue Position
Issue.Latitude = position.Latitude;
Issue.Longitude = position.Longitude;
Issue.Changed = true;
// Update Pin Postion
var pos = new Xamarin.Forms.Maps.Position(Issue.Latitude, Issue.Longitude);
map.Pins.Clear();
AddPin(pos, Issue.Title, Issue.Description);
UpdateGPSLocationText();
aActIndicator.IsRunning = false;
aActIndicator.IsVisible = false;
IsGettingLocation = false;
IsBusy = false;
slCommands.IsVisible = true;
this.ForceLayout();
// Center map around pin
MoveToPinLocation();
}
catch (Exception /*ex*/)
{
aActIndicator.IsRunning = false;
aActIndicator.IsVisible = false;
IsGettingLocation = false;
IsBusy = false;
slCommands.IsVisible = true;
lbPosText.Text = "Unable to find position!";
lbPosText.IsVisible = true;
this.ForceLayout();
}
}
void UpdateGPSLocationText()
{
String text = String.Format("{0} x {1}", Issue.Longitude, Issue.Latitude);
lbPosText.Text = text;
}
}
}
Android扩展地图渲染器
[assembly: ExportRenderer(typeof(ExtendedMap.ExtendedMap), typeof(ExtendedMapRenderer))]
namespace ExtendedMap.Android
{
public class ExtendedMapRenderer : MapRenderer, IOnMapReadyCallback
{
private GoogleMap _map;
public ExtendedMapRenderer()
{
}
public ExtendedMapRenderer(IntPtr javaReference, JniHandleOwnership jniHandleOwnership)
{
int x = 0;
x++;
}
private void InvokeOnMapReadyBaseClassHack(GoogleMap googleMap)
{
System.Reflection.MethodInfo onMapReadyMethodInfo = null;
Type baseType = typeof(MapRenderer);
foreach (var currentMethod in baseType.GetMethods(System.Reflection.BindingFlags.NonPublic |
System.Reflection.BindingFlags.Instance |
System.Reflection.BindingFlags.DeclaredOnly))
{
if (currentMethod.IsFinal && currentMethod.IsPrivate)
{
if (string.Equals(currentMethod.Name, "OnMapReady", StringComparison.Ordinal))
{
onMapReadyMethodInfo = currentMethod;
break;
}
if (currentMethod.Name.EndsWith(".OnMapReady", StringComparison.Ordinal))
{
onMapReadyMethodInfo = currentMethod;
break;
}
}
}
if (onMapReadyMethodInfo != null)
{
onMapReadyMethodInfo.Invoke(this, new[] { googleMap });
}
}
void IOnMapReadyCallback.OnMapReady(GoogleMap googleMap)
{
InvokeOnMapReadyBaseClassHack(googleMap);
_map = googleMap;
if (_map != null)
{
_map = googleMap;
this.NativeMap = googleMap;
_map.MapClick += googleMap_MapClick;
_map.MapLongClick += googleMap_MapLongClick;
((ExtendedMap)Element).OnReady();
}
}
protected override void OnElementChanged(ElementChangedEventArgs<Map> e)
{
if (_map != null)
_map.MapClick -= googleMap_MapClick;
base.OnElementChanged(e);
if (Control != null)
((MapView)Control).GetMapAsync(this);
}
private void googleMap_MapClick(object sender, GoogleMap.MapClickEventArgs e)
{
((ExtendedMap)Element).OnTap(new Position(e.Point.Latitude, e.Point.Longitude));
}
private void googleMap_MapLongClick(object sender, GoogleMap.MapLongClickEventArgs e)
{
((ExtendedMap)Element).OnLongTap(new Position(e.Point.Latitude, e.Point.Longitude));
}
}
}
答案 0 :(得分:0)
我会仔细检查您应用程序清单上的Google Maps API密钥!
<meta-data android:name="com.google.android.maps.v2.API_KEY" android:value="AIzr3yCpVgSOXvTgri29nC6KqFbdO73QmoVQWEw" />
以及Google API凭据信息中心上密钥库的SHA-1密钥。