Search code examples
c#xamarin.formspicker

Apply styles on Picker items in Xamarin Forms


I have a Picker, i want to apply different styles to all the items, also prefer if could do for IOS and Android at the same time.

in custom.xaml:

<ContentPage.Content>
        <StackLayout>
            <Picker
                x:Name="ArticuloPicker"
                Title="ADD"
                Margin="5"
                FontSize="16"
                HorizontalOptions="FillAndExpand"
                IsVisible="False"
                SelectedIndexChanged="OnPickerSelectedChanged" />

custom.xaml.cs:

protected override void OnAppearing()
        {
        base.OnAppearing();
        ArticuloPicker.ItemsSource = null; 

        //calculate description
        //example descripcion = "text"
        .
        .


            ArticuloPicker.Items.Add(descripcion);

        }
    }

I would like to assign a border to each picker.item , and maybe change font-color or other styling.

If anyone know how can i do or show me any example, i couldn't found anything properly done.

edit: What i want is to create a border and background for each item of the picker.

enter image description here


Solution

  • Here is a sample about Custom Renderer in Android & IOS.

    Create a custom picker:

    public class MyPicker : Picker
    {
    
    }
    

    Xaml:

    <local:MyPicker x:Name="picker" Title="Select An option" />
    

    ContentPage:

    picker.ItemsSource = new PickerModel().Monkeys;
    

    PcikerModel:

    public List<string> Monkeys { get; private set; }
    
    public PickerModel(){
        Monkeys = new List<string>();
    
        Monkeys.Add("Hello welcome to Custom PIicker Model");
        Monkeys.Add("Hello welcome to Custom PIicker Model");
        Monkeys.Add("Hello welcome to Custom PIicker Model");
        Monkeys.Add("Hello welcome to Custom PIicker Model");
        Monkeys.Add("Hello welcome to Custom PIicker Model");
        Monkeys.Add("Hello welcome to Custom PIicker Model");
        Monkeys.Add("Hello welcome to Custom PIicker Model");
        Monkeys.Add("Hello welcome to Custom PIicker Model");
        Monkeys.Add("Hello welcome to Custom PIicker Model");
        Monkeys.Add("Hello welcome to Custom PIicker Model");
        Monkeys.Add("Hello welcome to Custom PIicker Model");
    }
    

    Android:

    Create a custom renderer in Android:

    public class CustomPicker : PickerRenderer
    {
        private Dialog dialog;
    
        protected override void OnElementChanged(ElementChangedEventArgs<Picker> e)
        {
            base.OnElementChanged(e);
            Control.Click += Control_Click1;
        }
    
    
        protected override void Dispose(bool disposing)
        {
            Control.Click -= Control_Click1;
            base.Dispose(disposing);
        }
    
        private void Control_Click1(object sender, EventArgs e)
        {
            //throw new NotImplementedException();
            Picker model = Element;
            dialog = new Dialog(Forms.Context);
            dialog.SetContentView(Resource.Layout.custom_picker_dialog);
            Android.Widget.ListView listView = (Android.Widget.ListView)dialog.FindViewById(Resource.Id.listview);
            //listView.Adapter = new CustomPickerAdapter(((List<PickerModel>)model.ItemsSource), model.SelectedIndex);
            listView.Adapter = new MyAdaptr((List<string>)model.ItemsSource);
            listView.ItemClick += (object sender1, ItemClickEventArgs e1) =>
            {
                Element.SelectedIndex = e1.Position;
                dialog.Hide();
            };
            if (model.ItemsSource.Count > 3)
            {
                var height = Xamarin.Forms.Application.Current.MainPage.Height;
                var width = Xamarin.Forms.Application.Current.MainPage.Width;
                dialog.Window.SetLayout(700, 800);
                //dialog.Window.SetLayout(Convert.ToInt32(width * 2.70), Convert.ToInt32(height * 2));
            }
            dialog.Show();
        }
    
        class MyAdaptr : BaseAdapter
        {
            private IList<string> mList;
            public MyAdaptr(IList<string> itemsSource)
            {
                mList = itemsSource;
            }
    
    
    
            public override int Count => mList.Count;
    
    
    
            public override Java.Lang.Object GetItem(int position)
            {
                return mList[position];
            }
    
    
    
            public override long GetItemId(int position)
            {
                return position;
            }
    
    
    
            public override Android.Views.View GetView(int position, Android.Views.View convertView, ViewGroup parent)
            {
                Android.Views.View view = convertView;
                convertView = LayoutInflater.From(parent.Context).Inflate(Resource.Layout.celllayout, null);
                TextView text = convertView.FindViewById<TextView>(Resource.Id.textview1);
                text.Text = mList[position];
    
                return convertView;
            }
        }
    }
    

    From renderer need custom_picker_dialog.axml,celllayout.axml and shape_radius.axml

    custom_picker_dialog.axml:

    <?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"
        android:gravity="center"
        >
    
         <TextView
            android:text="Select One Option"
            android:layout_width="200dp"
            android:layout_height="25dp"
            android:paddingLeft="25dp"
            android:paddingRight="25dp"/>
    
          <ListView
          android:id="@+id/listview"
            android:layout_gravity="center"
          android:background="@drawable/abc_list_pressed_holo_light"
          android:layout_width="match_parent"
          android:dividerHeight="3dp"
          android:layout_height="0dp"
          android:layout_weight="1">
    
      </ListView>
    </LinearLayout>
    

    celllayout.axml:

    <?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"
        android:gravity="center">
    
    
       <TextView
        android:id="@+id/textview1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textColor="@android:color/holo_red_dark"
        android:background="@drawable/shape_redius"/>
    
    </LinearLayout>
    

    shape_radius.axml:

    <?xml version="1.0" encoding="utf-8"?>
    <shape xmlns:android="http://schemas.android.com/apk/res/android" >
      <corners android:radius="10dip"/>
      <solid android:color="#faaaaa"/>
      <stroke android:width="2dp" android:color="#000000"/>
    
    </shape>
    

    Finally effect is:

    enter image description here

    ============================================================================

    IOS:

    Create a custom renderer in ios:

    public class CustomPicker : PickerRenderer
    {
        List<string> itemList;
        protected override void OnElementChanged(ElementChangedEventArgs<Picker> e)
        {
            base.OnElementChanged(e);
    
    
            Picker myPicker = Element;
            itemList = myPicker.Items.ToList();
    
            UITextField textField = Control;
            UIPickerView pickerView = textField.InputView as UIPickerView;
            pickerView.Delegate = new MyPickerViewDelegate(itemList,Control);
            textField.InputView = pickerView;
    
            var toolbar = new UIToolbar(new CoreGraphics.CGRect(0, 0, UIScreen.MainScreen.Bounds.Size.Width , 1)) { BarStyle = UIBarStyle.Default, Translucent = true };
            textField.InputAccessoryView = toolbar;
        }
    }
    
    internal class MyPickerViewDelegate : UIPickerViewDelegate
    {
        private List<string> itemList;
        private UITextField textField;
        public MyPickerViewDelegate(List<string> itemList, UITextField control)
        {
            this.itemList = itemList;
            this.textField = control;
        }
    
        //Define the Font size or style
        public override NSAttributedString GetAttributedTitle(UIPickerView pickerView, nint row, nint component)
        {
            var text = new NSAttributedString(
                itemList[(int)row],
                font: UIFont.SystemFontOfSize(24),
                foregroundColor: UIColor.Red,
                strokeWidth: 4
            );
    
            return text;
        }
        //Define the row height
        public override nfloat GetRowHeight(UIPickerView pickerView, nint component)
        {
            return 45;
        }
    
        public override UIView GetView(UIPickerView pickerView, nint row, nint component, UIView view)
        {
            UIView contentView = new UIView(new CoreGraphics.CGRect(0, 0, UIScreen.MainScreen.Bounds.Size.Width, 45));
    
            UILabel label = new UILabel();
            label.Frame = contentView.Bounds;
            contentView.AddSubview(label);
    
            label.Text = itemList[(int)row];
            //Change the label style
            label.BackgroundColor = UIColor.Cyan;
            label.Layer.BorderWidth = 2;
            label.Layer.BorderColor = UIColor.Brown.CGColor;
            label.Layer.CornerRadius = 5;
    
            return contentView;
        }
    
        public override void Selected(UIPickerView pickerView, nint row, nint component)
        {
            //base.Selected(pickerView, row, component);
            textField.Text = itemList[(int)row];
            textField.ResignFirstResponder();
        }
    
    }
    

    And final effect is:

    enter image description here