2
votes

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

1
Better sharing image to show which effect is want.And if forms can not realize it , you also can use custom renderer to do.stackoverflow.com/questions/1262786/…Junior Jiang
@JuniorJiang-MSFT updated with photo of how picker shows, and what effects i want. Also, your link is from SQL question non related?ntzz
Thanks for updating ,I will check it ,and sorry for wrong link. Here is the right link .docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/…Junior Jiang
You can implement the Popup page and create the view like picker popup with your own list, view, style. Then hide the original picker and show some control inplace of picker. When user click on the replaced view, open your custom listview popup!Nirmal Subedi
@ntzz I have updated in answer.Junior Jiang

1 Answers

5
votes

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