我想添加一個自動完成服務到我的自定義搜索欄(我正在使用一個條目)Xamarin形式爲我的Xamarin形式地圖,但我一直無法這樣做。Xamarin谷歌地圖自動完成
我已經試過用XLabs,但沒有工作,至今我還沒有找到任何其他解決方案。
Xamarin.FormsMaps是否包含任何自動完成功能?或者Xamarin上是否有任何自動完成功能可能會丟失? 你推薦我什麼?如果您需要任何代碼或其他任何內容,請告訴我。
我想添加一個自動完成服務到我的自定義搜索欄(我正在使用一個條目)Xamarin形式爲我的Xamarin形式地圖,但我一直無法這樣做。Xamarin谷歌地圖自動完成
我已經試過用XLabs,但沒有工作,至今我還沒有找到任何其他解決方案。
Xamarin.FormsMaps是否包含任何自動完成功能?或者Xamarin上是否有任何自動完成功能可能會丟失? 你推薦我什麼?如果您需要任何代碼或其他任何內容,請告訴我。
這是一個很長的,但在這裏....很明顯,你會想把服務調用代碼class
和所有其他代碼ViewModel
。您也可能想要在服務調用方法中或周圍添加更多的空值和錯誤檢查。
我遺漏的一個重要部分是Google的要求,即在執行搜索時顯示Google徽標。因此請下載their icon並將其添加到用戶界面。我只在用戶關注Entry
時才顯示它。
所以這些都是地方的模型和我自己的Address
型號:
public class AddressInfo {
public string Address { get; set; }
public string City { get; set; }
public string State { get; set; }
public string ZipCode { get; set; }
public double Longitude { get; set; }
public double Latitude { get; set; }
}
public class PlacesMatchedSubstring {
[Newtonsoft.Json.JsonProperty("length")]
public int Length { get; set; }
[Newtonsoft.Json.JsonProperty("offset")]
public int Offset { get; set; }
}
public class PlacesTerm {
[Newtonsoft.Json.JsonProperty("offset")]
public int Offset { get; set; }
[Newtonsoft.Json.JsonProperty("value")]
public string Value { get; set; }
}
public class Prediction {
[Newtonsoft.Json.JsonProperty("id")]
public string Id { get; set; }
[Newtonsoft.Json.JsonProperty("description")]
public string Description { get; set; }
[Newtonsoft.Json.JsonProperty("matched_substrings")]
public List<PlacesMatchedSubstring> MatchedSubstrings { get; set; }
[Newtonsoft.Json.JsonProperty("place_id")]
public string PlaceId { get; set; }
[Newtonsoft.Json.JsonProperty("reference")]
public string Reference { get; set; }
[Newtonsoft.Json.JsonProperty("terms")]
public List<PlacesTerm> Terms { get; set; }
[Newtonsoft.Json.JsonProperty("types")]
public List<string> Types { get; set; }
}
public class PlacesLocationPredictions {
[Newtonsoft.Json.JsonProperty("predictions")]
public List<Prediction> Predictions { get; set; }
[Newtonsoft.Json.JsonProperty("status")]
public string Status { get; set; }
}
這裏我們所說的地方API:
public const string GooglePlacesApiAutoCompletePath = "https://maps.googleapis.com/maps/api/place/autocomplete/json?key={0}&input={1}&components=country:us"; //Adding country:us limits results to us
public const string GooglePlacesApiKey = "bTafrOPmO4LpPgAl34r5wQ6LFRWhgTxBW80-3GK";
private static HttpClient _httpClientInstance;
public static HttpClient HttpClientInstance => _httpClientInstance ?? (_httpClientInstance = new HttpClient());
private ObservableCollection<AddressInfo> _addresses;
public ObservableCollection<AddressInfo> Addresses {
get => _addresses ?? (_addresses = new ObservableCollection<AddressInfo>());
set {
if(_addresses != value) {
_addresses = value;
OnPropertyChanged();
}
};
}
private string _addressText;
public string AddressText {
get => _addressText;
set {
if(_addressText != value) {
_addressText = value;
OnPropertyChanged();
}
};
}
public async Task GetPlacesPredictionsAsync() {
// TODO: Add throttle logic, Google begins denying requests if too many are made in a short amount of time
CancellationToken cancellationToken = new CancellationTokenSource(TimeSpan.FromMinutes(2)).Token;
using(HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, string.Format(GooglePlacesApiAutoCompletePath, ConstantKeys.GooglePlacesApiKey, WebUtility.UrlEncode(_addressText)))) { //Be sure to UrlEncode the search term they enter
using(HttpResponseMessage message = await HttpClientInstance.SendAsync(request, HttpCompletionOption.ResponseContentRead, cancellationToken).ConfigureAwait(false)) {
if(message.IsSuccessStatusCode) {
string json = await message.Content.ReadAsStringAsync().ConfigureAwait(false);
PlacesLocationPredictions predictionList = await Task.Run(() => JsonConvert.DeserializeObject<PlacesLocationPredictions>(json)).ConfigureAwait(false);
if(predictionList.Status == "OK") {
Addresses.Clear();
if(predictionList.Predictions.Count > 0) {
foreach(Prediction prediction in predictionList.Predictions) {
Addresses.Add(new AddressInfo {
Address = prediction.Description
});
}
}
} else {
throw new Exception(predictionList.Status);
}
}
}
}
}
現在的UI ...
<Entry Text="{Binding AddressText}"
TextChanged="OnTextChanged" />
<ListView ItemsSource="{Binding Addresses}">
<ListView.ItemTemplate>
<DataTemplate>
<TextCell Text="{Binding Address}"/>
</DataTemplate>Text
</ListView.ItemTemplate>
</ListView>
及後面的代碼:
private async void OnTextChanged(object sender, EventArgs eventArgs) {
if(!string.IsNullOrWhiteSpace(ViewModel.AddressText)) {
await ViewModel.GetPlacesPredictionsAsync();
}
}
這正是我所需要的,如果我可以問,你如何獲得座標?你使用地理編碼器? –
@MauricioCárdenas來自'Prediction'類的座標?如果是這樣,是的。我使用Google Geocode API。幾乎相同的代碼,除了我使用服務調用的地理編碼網址,我反序列化到不同的模型的響應。 – hvaughan3
@ hvaughan3 is this line:await ViewModel.GetAddressCoordinatesAsync();應該調用GetPlacesPredictionsAsync? –
[Xamarin.Forms中的Google Place Autocomplete]可能的重複(https://stackoverflow.com/questions/34390423/google-place-autocomplete-in-xamarin-forms) – hvaughan3
@ hvaughan3我已經看到了一個,但它是一個獨家的android,這就是爲什麼沒有答案在這個問題上檢查。感謝壽。 –