RUDE

Xamarin — пользовательское средство выбора без NumberPicker

У меня есть пользовательский сборщик в моем проекте Xamarin, и мне требуется много времени, чтобы достичь того, чего я хочу.

Я хочу, чтобы мой CustomPicker отображался так

Вместо этого, так как я не могу центрировать слова, и быстрее выбрать другое.

Мне не нужна кнопка отмены, и я уже добился этого, но я не могу найти способ иметь и то, и другое.

  • Нет кнопки отмены
  • Вид выбора, как на первом изображении

Это мой CustomPicker класс

public class CustomPicker : Picker
    {
        public static readonly BindableProperty DonebuttonTextProperty = BindableProperty.Create("DonebuttonText", typeof(string),
            typeof(string), null);
        public string CancelButtonText
        {
            get { return (string)GetValue(DonebuttonTextProperty); }
            set { SetValue(DonebuttonTextProperty, value); }
        }
    }

Мой CustomPickerRenderer на Android


    public class CustomPickerRenderer : Xamarin.Forms.Platform.Android.AppCompat.PickerRenderer
    {
        public CustomPickerRenderer(Context context) : base(context) { }

        private IElementController ElementController => Element as IElementController;
        private AlertDialog _dialog;

        protected override void OnElementChanged(ElementChangedEventArgs<Picker> e)
        {
            base.OnElementChanged(e);

            if (e.NewElement == null || e.OldElement != null)
                return;

            Control.Click += Control_Click;

        }
        protected override void Dispose(bool disposing)
        {
            Control.Click -= Control_Click;
            base.Dispose(disposing);
        }

        private void Control_Click(object sender, EventArgs e)
        {
            Picker model = Element;

            var picker = new NumberPicker(Context);
            if (model.Items != null && model.Items.Any())
            {
                picker.MaxValue = model.Items.Count - 1;
                picker.MinValue = 0;
                picker.SetDisplayedValues(model.Items.ToArray());
                picker.WrapSelectorWheel = false;
                picker.DescendantFocusability = DescendantFocusability.BlockDescendants;
                picker.Value = model.SelectedIndex;
            }

            var layout = new LinearLayout(Context) { Orientation = Orientation.Vertical };
            layout.AddView(picker);

            ElementController.SetValueFromRenderer(VisualElement.IsFocusedProperty, true);

            var builder = new AlertDialog.Builder(Context);
            builder.SetView(layout);
            builder.SetTitle(model.Title ?? "");
            builder.SetPositiveButton("Done", (s, a) =>
            {
                ElementController.SetValueFromRenderer(Picker.SelectedIndexProperty, picker.Value);
                // It is possible for the Content of the Page to be changed on SelectedIndexChanged.
                // In this case, the Element & Control will no longer exist.
                if (Element != null)
                {
                    if (model.Items.Count > 0 && Element.SelectedIndex >= 0)
                        Control.Text = model.Items[Element.SelectedIndex];
                    ElementController.SetValueFromRenderer(VisualElement.IsFocusedProperty, false);
                    // It is also possible for the Content of the Page to be changed when Focus is changed.
                    // In this case, we'll lose our Control.
                    Control?.ClearFocus();
                }
                _dialog = null;
            });

            _dialog = builder.Create();
            _dialog.DismissEvent += (ssender, args) =>
            {
                ElementController?.SetValueFromRenderer(VisualElement.IsFocusedProperty, false);
            };
            _dialog.Show();
        }

    }

Как вы можете видеть, я использовал Xamarin.Forms.Platform.Android.AppCompat.Picker, чтобы использовать вид, который я хочу отобразить, но затем, если я использую NumberPicker, он будет отображаться как второе фото.

Пожалуйста, помогите, я не видел ни одного примера того, как это сделать, и я много искал. Спасибо.


34
1

Ответ:

Решено

Если вы хотите, чтобы средство выбора отображалось как на первом снимке экрана. Вы можете сбросить макет средства выбора, чтобы поместить элементы в список. Для разделителя между элементами в ietview вы можете установить divider ro null.

Xaml:

 <Picker x:Name = "picker"
Title = "Select"
TitleColor = "Red">
        <Picker.ItemsSource>
            <x:Array Type = "{x:Type x:String}">
                <x:String>item1</x:String>
                <x:String>item2</x:String>
                <x:String>item3</x:String>
                <x:String>item4</x:String>

            </x:Array>
        </Picker.ItemsSource>
    </Picker>

Пользовательский рендерер:

[assembly: ExportRenderer(typeof(Picker), typeof(CustomPickerRenderer2))]
namespace App1.Droid
{
public class CustomPickerRenderer2 : PickerRenderer
{
    AlertDialog listDialog;
    string[] items;
    public CustomPickerRenderer2(Context context) : base(context)
    {

    }
    protected override void OnElementChanged(ElementChangedEventArgs<Picker> e)
    {
        base.OnElementChanged(e);



        if (Control != null)
        {
            Control.Click += Control_Click; ;
        }

    }

    private void Control_Click(object sender, EventArgs e)
    {
        Picker model = Element;
        items = model.Items.ToArray();
        AlertDialog.Builder builder = new AlertDialog.Builder(this.Context);
        builder.SetTitle(model.Title ?? "");
        builder.SetNegativeButton("Cancel", (s, a) =>
        {
            Control?.ClearFocus();
            builder = null;
        });

        Android.Views.View view = LayoutInflater.From(this.Context).Inflate(Resource.Layout.listview, null);
        Android.Widget.ListView listView = view.FindViewById<Android.Widget.ListView>(Resource.Id.listView1);

        MyAdapter myAdapter = new MyAdapter(items, Element.SelectedIndex);
        listView.Adapter = myAdapter;
        listView.ItemClick += ListView_ItemClick;
        builder.SetView(view);
        listDialog = builder.Create();

        listDialog.Show();

    }

    private void ListView_ItemClick(object sender, AdapterView.ItemClickEventArgs e)
    {
        Control.Text = items[e.Position];
        Element.SelectedIndex = e.Position;
        Console.WriteLine(items[e.Position]);
        listDialog.Dismiss();
        listDialog = null;
    }
}

class MyAdapter : BaseAdapter
{
    private string[] items;
    private int selectedIndex;

    public MyAdapter(string[] items)
    {
        this.items = items;
    }

    public MyAdapter(string[] items, int selectedIndex) : this(items)
    {
        this.selectedIndex = selectedIndex;
    }

    public override int Count => items.Length;

    public override Java.Lang.Object GetItem(int position)
    {
        return items[position];
    }

    public override long GetItemId(int position)
    {
        return position;
    }

    public override Android.Views.View GetView(int position, Android.Views.View convertView, ViewGroup parent)
    {
        if (convertView == null)
        {
            convertView = LayoutInflater.From(parent.Context).Inflate(Resource.Layout.listview_item, null);
        }
        TextView textView = convertView.FindViewById<TextView>(Resource.Id.textView1);
        textView.Text = items[position];
        return convertView;
    }
}
}

Listview.xml: Вы можете создать в своем проекте Resources/layout в Android.

<?xml version = "1.0" encoding = "utf-8"?>
<LinearLayout xmlns:android = "http://schemas.android.com/apk/res/android"
    android:orientation = "vertical"
    android:layout_width = "match_parent"
    android:layout_height = "match_parent">
     <ListView
   android:id = "@+id/listView1"           
  android:divider = "@null"
   android:layout_width = "match_parent"
   android:layout_height = "wrap_content"/> 


</LinearLayout>

Listview_item.xml: вы можете создать в своем проекте Resources/layout в Android.

<?xml version = "1.0" encoding = "utf-8"?>
<LinearLayout xmlns:android = "http://schemas.android.com/apk/res/android"
    android:orientation = "vertical"
    android:layout_width = "match_parent"
    android:layout_height = "match_parent">
   <TextView
      android:id = "@+id/textView1"
      android:layout_width = "match_parent"
      android:layout_height = "wrap_content"/>
</LinearLayout>