我正在处理我正在处理的项目的问题。我最近开始学习C#并成功构建了Xamarin Forms的基本程序。
我正潜入一个相当大的项目并继续学习。
我目前遇到的问题是生成一个以设备当前位置为中心的地图页面。我已经将问题缩小到我所认为的位置,一旦获得该位置没有被保存到我已声明的变量中,以便我可以用另一种方法访问它。
public partial class MapPage : ContentPage
{
public static double latitude;
public static double longitude;
public MapPage()
{
InitializeComponent();
GetCurrentLocation();
var map = new Map(MapSpan.FromCenterAndRadius(
new Position(latitude, longitude), Distance.FromMiles(.3)))
{
MapType = MapType.Street,
IsShowingUser = true,
HeightRequest = 100,
WidthRequest = 960,
VerticalOptions = LayoutOptions.FillAndExpand,
HasScrollEnabled = true,
HasZoomEnabled = true
};
var stack = new StackLayout { Spacing = 0 };
stack.Children.Add(map);
Content = stack;
}
private static async void GetCurrentLocation()
{
var locator = CrossGeolocator.Current;
locator.DesiredAccuracy = 50;
var position = await locator.GetPositionAsync(timeoutMilliseconds: 10000);
latitude = position.Latitude;
longitude = position.Longitude;
}
}
当使用上面的代码显示地图时,它接收纬度和经度(0,0)。我已经使用断点和调试验证了纬度和经度被检索并存储在"位置"但是我并不相信它存储在我的纬度和经度变量中。
知道我在这里缺少什么吗?
答案 0 :(得分:0)
public async override void OnAppearing()
{
var pos = await GetCurrentLocation();
var map = new Map(MapSpan.FromCenterAndRadius(
pos, Distance.FromMiles(.3)))
{
MapType = MapType.Street,
IsShowingUser = true,
HeightRequest = 100,
WidthRequest = 960,
VerticalOptions = LayoutOptions.FillAndExpand,
HasScrollEnabled = true,
HasZoomEnabled = true
};
var stack = new StackLayout { Spacing = 0 };
stack.Children.Add(map);
Content = stack;
}
private async Position GetCurrentLocation()
{
var locator = CrossGeolocator.Current;
locator.DesiredAccuracy = 50;
var position = await locator.GetPositionAsync(timeoutMilliseconds: 10000);
return position;
}
答案 1 :(得分:0)
您的代码中有应该注意的几件事:
检索位置的方法'GetCurrentLocation()'是异步的。如果失败,您的应用程序将失败。你应该少用这个方法中的try {} catch {}。 Personaly,为了便于阅读,我还为异步方法添加了“Async”后缀(即:GetCurrentLoactionAsync())。
接下来,您将从构造函数中调用“异步”方法。但是在构造函数中,您不能等待异步方法(等待结果)。这就是为什么你总是有一个空位。你不应该从这里调用这个方法。
如提到的@Jason,您可以覆盖'OnAppearing()'方法来加载数据。这是一个更好的地方。但请注意使用'await'关键字并在try / catch块中调用该方法,因为'OnAppearing()'不会返回任务。
最后,我建议您在XAML代码部分中创建地图(因此地图已经存在,并且在加载位置之前不会有空白页面)。然后在OnAppearing()中使用posistion初始化地图(它可能会通过重新定位在地图上生成动画。我认为这更令人愉快;)。
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MediaSample.MapPage">
<ContentPage.Content>
<Grid>
<!-- your map object -->
<Map x:Name="uiMap" />
<!-- whatever you want -->
</Grid>
</ContentPage.Content>
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class MapPage : ContentPage
{
public MapPage()
{
InitializeComponent();
}
protected override async void OnAppearing()
{
base.OnAppearing();
try
{
// get your position
var centerPos = await GetCurrentLocation();
// init map => center on the position
uiMap.MoveToRegion(MapSpan.FromCenterAndRadius(centerPos, Distance.FromMiles(.3)).WithZoom(20));
}
catch(Exception e)
{
// notify user here
// log exception
}
}
private async Task<Position> GetCurrentLocation()
{
var locator = CrossGeolocator.Current;
locator.DesiredAccuracy = 50;
var position = await locator.GetPositionAsync(timeoutMilliseconds: 10000);
return position;
}
}