Google Place Autocomplete in Xamarin.Forms

半城伤御伤魂 提交于 2019-12-10 13:54:21

问题


Has anyone integrated Google Place Autocomplete using Xamarin.Forms? I am to use it on a map for location suggestions. I've only seen resources for Xamarin.Android and Xamarin.iOS but on the part of implementing the AutoCompleteView, that I also don't know. I would be very thankful if someone could guide me with this. Thank you!


回答1:


Place autocomplete can be implemented by using the Google Place API, whenever user enter a character, matching location with the entered character will be fetched from the Google server and binding back in User Interface.

Here's the link how to use Google Map Place API in Xamarin form: http://www.appliedcodelog.com/2015/05/google-place-api-with-autocomplete-in.html

Also, please read the Official Google Places API Web Service: https://developers.google.com/places/web-service/autocomplete




回答2:


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

And this is location view controller

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


来源:https://stackoverflow.com/questions/34390423/google-place-autocomplete-in-xamarin-forms

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!