【问题标题】:Xamarin Forms Geolocator IOSXamarin 形成地理定位器 IOS
【发布时间】:2017-06-18 04:30:19
【问题描述】:

我正在处理的项目遇到问题。我最近开始学习 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) 的纬度和经度。我已经使用断点和调试验证了纬度和经度正在被检索并存储在“位置”变量中,但是我不相信它被存储在我的纬度和经度变量中。

知道我在这里缺少什么吗?

【问题讨论】:

    标签: c# xamarin.ios xamarin.android xamarin.forms


    【解决方案1】:
    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;
    }
    

    【讨论】:

      【解决方案2】:

      您的代码中有您应该注意的几件事

      • 检索位置的方法“GetCurrentLocation()”是异步的。如果失败,您的应用程序将失败。您应该在此方法中少用 try{ } catch{}。就个人而言,为了便于阅读,我还在异步方法中添加了“Async”后缀(即:GetCurrentLoactionAsync())。

      • 接下来,您从构造函数中调用“异步”方法。但是在您的构造函数中,您不能等待异步方法(等待结果)。这就是为什么你总是有一个空位置。你不应该从这里调用这个方法。

      • 正如@Jason 提到的,您可以覆盖“OnAppearing()”方法来加载数据。这是一个更好的地方。但请注意使用“await”关键字并在 try/catch 块中调用该方法,因为“OnAppearing()”不会返回任务。

      • 最后,我建议您在 XAML 代码部分中创建地图(因此地图已经存在,并且在加载位置之前您不会有空白页)。然后在 OnAppearing() 中使用位置初始化地图(它可能会通过重新定位在地图上生成动画。我认为这更令人愉快;)。

      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"
               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;
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-09-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-05-26
        相关资源
        最近更新 更多