Xamarin - 没有 NumberPicker 的自定义选择器

Xamarin - Custom Picker without NumberPicker

我的 Xamarin 项目中有一个自定义选择器,我花了很长时间才达到我想要的效果。

我希望我的 CustomPicker 像这样显示

而不是这个,因为我无法将单词居中,而且 select 与另一个单词相比会更快。

我不想要取消按钮,我已经实现了,但我想不出同时拥有这两个按钮的方法

这是我的CustomPickerclass

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,它将像第二张照片一样显示。

请帮助我还没有看到任何关于如何执行此操作的示例,我一直在搜索很多。谢谢。

如果您希望选择器像第一个屏幕截图那样显示。您可以重置选择器布局以将项目放在列表视图中。对于 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:您可以在 android 项目中创建 Resources/layout

<?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 :您可以在 android 项目中的 Resources/layout 中创建。

<?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>