using System; using System.ComponentModel; using System.Linq; using Android.App; using Android.Content.Res; using Android.Text; using Android.Widget; using Object = Java.Lang.Object; namespace Xamarin.Forms.Platform.Android.AppCompat { public class PickerRenderer : ViewRenderer { AlertDialog _dialog; bool _disposed; TextColorSwitcher _textColorSwitcher; public PickerRenderer() { AutoPackage = false; } protected override EditText CreateNativeControl() { return new EditText(Context); } protected override void Dispose(bool disposing) { if (disposing && !_disposed) { _disposed = true; ((ObservableList)Element.Items).CollectionChanged -= RowsCollectionChanged; } base.Dispose(disposing); } protected override void OnElementChanged(ElementChangedEventArgs e) { if (e.OldElement != null) ((ObservableList)e.OldElement.Items).CollectionChanged -= RowsCollectionChanged; if (e.NewElement != null) { ((ObservableList)e.NewElement.Items).CollectionChanged += RowsCollectionChanged; if (Control == null) { EditText textField = CreateNativeControl(); textField.Focusable = false; textField.Clickable = true; textField.Tag = this; textField.InputType = InputTypes.Null; textField.SetOnClickListener(PickerListener.Instance); _textColorSwitcher = new TextColorSwitcher(textField.TextColors); SetNativeControl(textField); } UpdatePicker(); UpdateTextColor(); } base.OnElementChanged(e); } protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e) { base.OnElementPropertyChanged(sender, e); if (e.PropertyName == Picker.TitleProperty.PropertyName) UpdatePicker(); if (e.PropertyName == Picker.SelectedIndexProperty.PropertyName) UpdatePicker(); if (e.PropertyName == Picker.TextColorProperty.PropertyName) UpdateTextColor(); } internal override void OnFocusChangeRequested(object sender, VisualElement.FocusRequestArgs e) { base.OnFocusChangeRequested(sender, e); if (e.Focus) OnClick(); else if (_dialog != null) { _dialog.Hide(); ((IElementController)Element).SetValueFromRenderer(VisualElement.IsFocusedPropertyKey, false); Control.ClearFocus(); _dialog = null; } } void OnClick() { Picker model = Element; if (_dialog == null) { using (var builder = new AlertDialog.Builder(Context)) { builder.SetTitle(model.Title ?? ""); string[] items = model.Items.ToArray(); builder.SetItems(items, (s, e) => ((IElementController)model).SetValueFromRenderer(Picker.SelectedIndexProperty, e.Which)); builder.SetNegativeButton(global::Android.Resource.String.Cancel, (o, args) => { }); ((IElementController)Element).SetValueFromRenderer(VisualElement.IsFocusedPropertyKey, true); _dialog = builder.Create(); } _dialog.SetCanceledOnTouchOutside(true); _dialog.DismissEvent += (sender, args) => { ((IElementController)Element).SetValueFromRenderer(VisualElement.IsFocusedPropertyKey, false); _dialog.Dispose(); _dialog = null; }; _dialog.Show(); } } void RowsCollectionChanged(object sender, EventArgs e) { UpdatePicker(); } void UpdatePicker() { Control.Hint = Element.Title; if (Element.SelectedIndex == -1 || Element.Items == null) Control.Text = null; else Control.Text = Element.Items[Element.SelectedIndex]; } void UpdateTextColor() { _textColorSwitcher?.UpdateTextColor(Control, Element.TextColor); } class PickerListener : Object, IOnClickListener { #region Statics public static readonly PickerListener Instance = new PickerListener(); #endregion public void OnClick(global::Android.Views.View v) { var renderer = v.Tag as PickerRenderer; renderer?.OnClick(); } } } }