Google Place Autocomplete in Xamarin.Forms
是否有人使用Xamarin.Forms集成了Google Place自动完成功能?我将在地图上使用它来提供位置建议。我只看到Xamarin.Android和Xamarin.iOS的资源,但实现AutoCompleteView的部分,我也不知道。如果有人能指导我,我会非常感激。谢谢!Google Place Autocomplete in Xamarin.Forms
通过使用Google Place API可以实现地方自动完成功能,无论何时用户输入一个字符,匹配的位置和输入的字符都会从Google服务器获取并绑定回用户界面。
这里的链接如何使用谷歌地图将API在Xamarin形式: http://www.appliedcodelog.com/2015/05/google-place-api-with-autocomplete-in.html
另外,请阅读谷歌官方Places API的Web服务: https://developers.google.com/places/web-service/autocomplete
这不是Xamarin.Forms,我认为这是Xamarin.Android。是的,它使用Google Place API。它通常使用的是从AutocompleteTextView实现的,我不确定它是否适用于Xamarin.Forms中的正常条目,是吗?嗯。 – AlexaMayer
对于iOS
[assembly: ExportRenderer(typeof(CustomAutoCompleteLocation), typeof(CustomAutoCompleteRenderer))]
namespace Aesthetic.iOS.Renderer
{
public class CustomAutoCompleteProfileRenderer : EntryRenderer
{
IntPtr inptr;
string tx = "1";
CustomAutoCompleteLocation _view;
Place place;
UITextField textView;
public UIWindow Window
{
get;
set;
}
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{
base.OnElementChanged(e);
_view = (CustomAutoCompleteLocation)Element;
if (Control != null)
{
textView = (UITextField)Control;
textView.Font = UIFont.FromName("Lato-Light", textView.Font.PointSize);
textView.BorderStyle = UITextBorderStyle.Line;
textView.Layer.BorderWidth = 1f;
textView.Layer.CornerRadius = 0f;
// do whatever you want to the textField here!
UIView paddingView = new UIView(new RectangleF(10, 16, 10, 16));
textView.LeftView = paddingView;
textView.LeftViewMode = UITextFieldViewMode.Always;
}
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
var x = sender as CustomAutoComplete;
if (e.PropertyName == "IsFocused")
{
if (tx == "1")
{
Device.BeginInvokeOnMainThread(() =>
{
Window = new UIWindow(UIScreen.MainScreen.Bounds);
var controller = new LocationViewController();
Window.RootViewController = controller;
// make the window visible
Window.MakeKeyAndVisible();
controller.PlaceSelected1 += HandlePlaceSelection;
});
tx = "2";
}
else if (tx == "2") tx = "3";
else if (tx == "3") tx = "4";
else if (tx == "4") tx = "1";
}
}
private void HandlePlaceSelection(object sender, string locationData)
{
textView.Text = locationData;
Window.Hidden = true;
}
}
}
这是位置视图控制器
public partial class LocationViewController : UIViewController
{
public delegate void PlaceSelected(object sender, string locationData);
UITextField txtLocation;
public UIView backgroundView;
// UITextView txtLocation;
UIImageView googleAttribution;
UITableView tableViewLocationAutoComplete;
public event PlaceSelected PlaceSelected1;
public string strSampleString { get; set; }
LocationPredictionClass objAutoCompleteLocationClass;
string strAutoCompleteQuery;
LocationAutoCompleteTableSource objLocationAutoCompleteTableSource;
public LocationViewController() : base()
{
}
public override void ViewDidLoad()
{
base.ViewDidLoad();
FnInitializeView();
FnClickEventInit();
}
void FnInitializeView()
{
backgroundView = new UIView(View.Frame);
backgroundView.BackgroundColor = UIColor.White;
View.AddSubview(backgroundView);
txtLocation = new UITextField();
txtLocation.Frame = new CoreGraphics.CGRect(20, 20, View.Frame.Width-20, 45.0f);
txtLocation.TranslatesAutoresizingMaskIntoConstraints = false;
txtLocation.ReturnKeyType = UIReturnKeyType.Done;
txtLocation.BackgroundColor = UIColor.FromRGB(221,221,221);
txtLocation.TextColor = UIColor.Black;
View.AddSubview(txtLocation);
txtLocation.BecomeFirstResponder();
tableViewLocationAutoComplete = new UITableView();
tableViewLocationAutoComplete.Frame = new CoreGraphics.CGRect(txtLocation.Frame.X, txtLocation.Frame.Height+ txtLocation.Frame.Y, View.Frame.Width, View.Frame.Height - txtLocation.Frame.Height - txtLocation.Frame.Y);
tableViewLocationAutoComplete.BackgroundColor = UIColor.White;
tableViewLocationAutoComplete.Source = objLocationAutoCompleteTableSource;
View.AddSubview(tableViewLocationAutoComplete);
tableViewLocationAutoComplete.Hidden = false;
txtLocation.ShouldReturn += (textField) => textField.ResignFirstResponder();
StringBuilder builderLocationAutoComplete = new StringBuilder(Constants.strPlacesAutofillUrl);
builderLocationAutoComplete.Append("?input={0}").Append("&key=").Append(Constants.strGooglePlaceAPILey);
strAutoCompleteQuery = builderLocationAutoComplete.ToString();
builderLocationAutoComplete.Clear();
builderLocationAutoComplete = null;
}
void FnClickEventInit()
{
txtLocation.EditingChanged += async delegate (object sender, EventArgs e)
{
if (string.IsNullOrWhiteSpace(txtLocation.Text))
{
tableViewLocationAutoComplete.Hidden = true;
}
else
{
if (txtLocation.Text.Length > 2)
{
//Autofill
string strFullURL = string.Format(strAutoCompleteQuery, txtLocation.Text);
objAutoCompleteLocationClass = await RestRequestClass.LocationAutoComplete(strFullURL);
if (objAutoCompleteLocationClass != null && objAutoCompleteLocationClass.status == "OK")
{
if (objAutoCompleteLocationClass.predictions.Count > 0)
{
if (objLocationAutoCompleteTableSource != null)
{
objLocationAutoCompleteTableSource.LocationRowSelectedEventAction -= LocationSelectedFromAutoFill;
objLocationAutoCompleteTableSource = null;
}
tableViewLocationAutoComplete.Hidden = false;
objLocationAutoCompleteTableSource = new LocationAutoCompleteTableSource(objAutoCompleteLocationClass.predictions);
objLocationAutoCompleteTableSource.LocationRowSelectedEventAction += LocationSelectedFromAutoFill;
tableViewLocationAutoComplete.Source = objLocationAutoCompleteTableSource;
tableViewLocationAutoComplete.ReloadData();
}
else
tableViewLocationAutoComplete.Hidden = true;
}
else
{
tableViewLocationAutoComplete.Hidden = true;
}
}
}
};
}
void LocationSelectedFromAutoFill(Prediction objPrediction)
{
DismissViewController(true, null);
Console.WriteLine(objPrediction.description);
PlaceSelected1(this, objPrediction.description);
txtLocation.ResignFirstResponder();
}
}
public class RestRequestClass
{
static async Task<string> CallService(string strURL)
{
WebClient client = new WebClient();
string strResult;
try
{
strResult = await client.DownloadStringTaskAsync(new Uri(strURL));
}
catch
{
strResult = "Exception";
}
finally
{
client.Dispose();
client = null;
}
return strResult;
}
internal static async Task<LocationPredictionClass> LocationAutoComplete(string strFullURL)
{
LocationPredictionClass objLocationPredictClass = null;
LocationPredictionClass objLocationPredictClass12 = new LocationPredictionClass();
objLocationPredictClass12.predictions = new List<Prediction>();
string strResult = await CallService(strFullURL);
if (strResult != "Exception")
{
objLocationPredictClass = JsonConvert.DeserializeObject<LocationPredictionClass>(strResult);
}
foreach (Prediction objPred in objLocationPredictClass.predictions)
{
if (objPred.types[0] == "country")
{
objLocationPredictClass12.predictions.Add(objPred);
objLocationPredictClass12.status = "OK";
}
}
// string[] strPredictiveText = new string[data.Count];
//int index = 0;
// foreach (Prediction objPred in data)
// {
// strPredictiveText[index] = objPred.description;
// index++;
// }
return objLocationPredictClass12;
}
}
public class MatchedSubstring
{
public int length { get; set; }
public int offset { get; set; }
}
public class Term
{
public int offset { get; set; }
public string value { get; set; }
}
public class Prediction
{
public string description { get; set; }
public string id { get; set; }
public List<MatchedSubstring> matched_substrings { get; set; }
public string place_id { get; set; }
public string reference { get; set; }
public List<Term> terms { get; set; }
public List<string> types { get; set; }
}
public class LocationPredictionClass
{
public List<Prediction> predictions { get; set; }
public string status { get; set; }
}
public class Constants
{
public static string strGooglePlaceAPILey = "AIzaSyBXJntNIs2aAvKIRwrgCEwOGwnigbSWep8";
public static string strPlacesAutofillUrl = "https://maps.googleapis.com/maps/api/place/autocomplete/json";
}
public class LocationAutoCompleteTableSource : UITableViewSource
{
const string strCellIdentifier = "Cell";
readonly List<Prediction> lstLocations;
internal event Action<Prediction> LocationRowSelectedEventAction;
public LocationAutoCompleteTableSource(List<Prediction> arrItems)
{
lstLocations = arrItems;
}
public override nint RowsInSection(UITableView tableview, nint section)
{
return lstLocations.Count;
}
public override UIView GetViewForFooter(UITableView tableView, nint section)
{
return new UIView();
}
public override UITableViewCell GetCell(UITableView tableView, Foundation.NSIndexPath indexPath)
{
UITableViewCell cell = tableView.DequeueReusableCell(strCellIdentifier) ?? new UITableViewCell(UITableViewCellStyle.Default, strCellIdentifier);
cell.TextLabel.Text = lstLocations[indexPath.Row].description;
cell.TextLabel.Font = UIFont.SystemFontOfSize(12);
return cell;
}
public override void RowSelected(UITableView tableView, Foundation.NSIndexPath indexPath)
{
if (LocationRowSelectedEventAction != null)
{
LocationRowSelectedEventAction(lstLocations[indexPath.Row]);
}
tableView.DeselectRow(indexPath, true);
}
}
}
如果您使用的Google地图自动完成功能未使用Google地图控件,[其政策状态](https://developers.google.com/places/web-service/policies#logo_requirements)需要包含其特定的“Powered由Google“在您的自动完成控件所在页面上标识。 – hvaughan3