如何在Xamarin.Forms中实现Google PlaceAutocompletePrediction及完整代码示例
报错问题快速修复
你遇到的“非静态字段、方法或属性需要对象引用”报错,核心原因是ServiceClass1中的AddressText属性、GetPlacesPredictionsAsync方法未设置为静态,不能直接通过类名调用,有两种修复方案:
- 方案1:修改ServiceClass1成员为静态
public static class ServiceClass1 { public static string AddressText { get; set; } public static async Task<List<PlacePrediction>> GetPlacesPredictionsAsync() { // 原有业务逻辑保持不变 } }
- 方案2:实例化后调用(更推荐,方便多场景复用)
先在页面类中声明全局实例:
private ServiceClass1 _placeService = new ServiceClass1();
再修改TextChanged事件代码:
private async void Entry_TextChanged(object sender, TextChangedEventArgs e) { _placeService.AddressText = e.NewTextValue; if (!string.IsNullOrWhiteSpace(_placeService.AddressText)) { var predictionList = await _placeService.GetPlacesPredictionsAsync(); // 预测结果绑定到列表控件显示 PlaceSuggestionList.ItemsSource = predictionList; } else { PlaceSuggestionList.ItemsSource = null; } }
Xamarin Forms 谷歌地址预测功能完整实现步骤
2.1 前置准备
- 到谷歌云平台开通Places API服务,获取API密钥,注意开启计费(谷歌提供免费额度,普通开发测试不会产生费用)
- NuGet安装依赖:
Newtonsoft.Json、Xamarin.Forms
2.2 定义预测结果模型类
public class PlacePrediction { [JsonProperty("description")] public string Description { get; set; } [JsonProperty("place_id")] public string PlaceId { get; set; } } public class PlaceAutoCompleteResponse { [JsonProperty("predictions")] public List<PlacePrediction> Predictions { get; set; } [JsonProperty("status")] public string Status { get; set; } }
2.3 封装地址预测服务类
public class GooglePlaceService { private const string ApiKey = "替换为自己的谷歌云Places API密钥"; private const string AutoCompleteApiUrl = "https://maps.googleapis.com/maps/api/place/autocomplete/json?input={0}&key={1}"; public async Task<List<PlacePrediction>> GetPlacePredictions(string inputText) { if (string.IsNullOrWhiteSpace(inputText)) return new List<PlacePrediction>(); using (var httpClient = new HttpClient()) { var requestUrl = string.Format(AutoCompleteApiUrl, Uri.EscapeDataString(inputText), ApiKey); var response = await httpClient.GetStringAsync(requestUrl); var result = JsonConvert.DeserializeObject<PlaceAutoCompleteResponse>(response); return result.Status == "OK" ? result.Predictions : new List<PlacePrediction>(); } } }
2.4 页面XAML布局
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="YourNamespace.PlaceSearchPage"> <StackLayout Padding="16"> <!-- 地址输入框 --> <Entry x:Name="AddressEntry" Placeholder="请输入地址" TextChanged="AddressEntry_TextChanged"/> <!-- 预测建议列表 --> <ListView x:Name="PredictionList" HasUnevenRows="True" ItemSelected="PredictionList_ItemSelected"> <ListView.ItemTemplate> <DataTemplate> <TextCell Text="{Binding Description}" /> </DataTemplate> </ListView.ItemTemplate> </ListView> </StackLayout> </ContentPage>
2.5 页面后台逻辑
public partial class PlaceSearchPage : ContentPage { private readonly GooglePlaceService _placeService = new GooglePlaceService(); public PlaceSearchPage() { InitializeComponent(); } private async void AddressEntry_TextChanged(object sender, TextChangedEventArgs e) { // 增加输入长度校验+防抖,避免频繁请求接口 if (e.NewTextValue.Length < 2) { PredictionList.ItemsSource = null; return; } var predictions = await _placeService.GetPlacePredictions(e.NewTextValue); PredictionList.ItemsSource = predictions; } private async void PredictionList_ItemSelected(object sender, SelectedItemChangedEventArgs e) { if (e.SelectedItem is PlacePrediction selectedPrediction) { // 用户选中建议后的逻辑,此处示例为回填到输入框 AddressEntry.Text = selectedPrediction.Description; PredictionList.ItemsSource = null; // 后续如果需要获取地址经纬度,可通过place_id调用谷歌Place Details接口实现 } } }
注意事项
- 安卓、iOS端需要提前配置网络权限:安卓在AndroidManifest.xml中添加
ACCESS_NETWORK_STATE、INTERNET权限;iOS在Info.plist中配置网络请求允许规则 - 生产环境建议增加接口防抖逻辑,减少无效API调用次数
- 谷歌API密钥不要明文硬编码在客户端代码中,生产环境建议走自有后端代理请求,避免密钥泄露
内容的提问来源于stack exchange,提问作者Patrick89
相关产品推荐
相关产品推荐

