首页 > 解决方案 > 如何使用xamarin表单android中的自定义渲染器在两行中设置选择器行项目长文本?

问题描述

我想使用自定义渲染在两行中显示选择器项的长文本,我该如何实现?

标签: xamarinxamarin.formsxamarin.android

解决方案


首先,您需要一个自定义的picker 渲染器。

要覆盖该项目,您需要将原始视图替换为AlertDialog.

然后自定义 aListView并将其设置为AlertDialog.View.

然后就可以自定义里面的所有东西了Adapter(这里我们需要自定义textview)。

示例代码

[assembly: ExportRenderer(typeof(Picker), typeof(MyPickerRenderer))]
namespace FormsApp.Droid
{

    public class MyAdapter : ArrayAdapter
    {
        private IList<string> _data;
        Context _context;
        public MyAdapter(Context context, int resource , IList<string> data) : base(context,resource)
        {
            _context = context;
            _data = data;
        }

        public override int Count => _data.Count;

        public override Android.Views.View GetView(int position, Android.Views.View convertView, ViewGroup parent)
        {

            TextView textview = new TextView(_context);
            textview.TextSize = 18;
            textview.SetTextColor(Android.Graphics.Color.DarkGray);
            textview.Ellipsize = TruncateAt.End;
            textview.SetMaxLines(2);   //this line 
            textview.Text = _data[position];
            return textview;     
        }
    }

    public class MyListView : Android.Widget.ListView
    {
        public MyListView(Context context, IList<string> data) : base(context)
        {
            this.DividerHeight = 0;
            this.Adapter = new MyAdapter(context, 0, data);
        }

    }


    class MyPickerRenderer : Xamarin.Forms.Platform.Android.AppCompat.PickerRenderer
    {
        IElementController ElementController => Element as IElementController;

        public MyPickerRenderer(Context context):base(context)
        {

        }

        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 MyListView(Context, model.Items);
             

            var layout = new LinearLayout(Context) { Orientation = Orientation.Vertical };
            layout.SetPadding(35, 30, 35, 0);
            layout.AddView(picker);

            ElementController.SetValueFromRenderer(VisualElement.IsFocusedProperty, true);

            var builder = new AlertDialog.Builder(Context);
            builder.SetView(layout);

            builder.SetTitle(model.Title ?? "");
            builder.SetNegativeButton("Cancel  ", (s, a) =>
            {
                ElementController.SetValueFromRenderer(VisualElement.IsFocusedProperty, false);
                // It is 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();
        }

    }
}

在 Forms xaml 中测试代码

    <Picker x:Name="picker" Title="Select a monkey">
        <Picker.ItemsSource>
            <x:Array Type="{x:Type x:String}">
                <x:String>abc</x:String>
                <x:String>aaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbccccccccccccccccdddddddddddddddddddddd</x:String>
            </x:Array>
        </Picker.ItemsSource>
    </Picker>

在此处输入图像描述

在此处输入图像描述


推荐阅读