6

有没有人使用 Xamarin.Forms 集成 Google Place Autocomplete?我将在地图上使用它来提供位置建议。我只看到了 Xamarin.Android 和 Xamarin.iOS 的资源,但在实现 AutoCompleteView 的部分,我也不知道。如果有人可以指导我,我将非常感激。谢谢!

4

2 回答 2

4

地点自动完成可以通过使用 Google Place API 来实现,每当用户输入字符时,将从 Google 服务器获取与输入字符匹配的位置并绑定回用户界面。

以下是如何以 Xamarin 形式使用 Google Map Place API 的链接:http: //www.appliedcodelog.com/2015/05/google-place-api-with-autocomplete-in.html

另外,请阅读官方 Google Places API 网络服务: https ://developers.google.com/places/web-service/autocomplete

于 2015-12-22T02:10:56.240 回答
0

对于 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);
        }
    }
}
于 2017-02-09T14:03:47.240 回答