在 Xamarin Forms 中的 Picker 项目上应用样式

Posted

技术标签:

【中文标题】在 Xamarin Forms 中的 Picker 项目上应用样式【英文标题】:Apply styles on Picker items in Xamarin Forms 【发布时间】:2019-07-17 14:33:58 【问题描述】:

我有一个 Picker,我想为所有项目应用不同的样式,如果可以同时为 iosandroid 做,我也更喜欢。

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);

        
    

我想为每个 picker.item 分配一个边框,并可能更改字体颜色或其他样式。

如果有人知道我该怎么做或向我展示任何示例,我找不到任何正确的做法。

编辑:我想要的是为选择器的每个项目创建一个边框和背景。

【问题讨论】:

更好的分享图片来显示想要的效果。如果表单无法实现,也可以使用自定义渲染器来做。***.com/questions/1262786/… @JuniorJiang-MSFT 更新了选择器显示方式以及我想要什么效果的照片。另外,您的链接来自不相关的 SQL 问题? 感谢更新,我会检查它,并抱歉错误的链接。这是正确的链接。docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/… 您可以实现弹出页面并使用您自己的列表、视图、样式创建类似于选择器弹出窗口的视图。然后隐藏原始选择器并显示一些控件代替选择器。当用户点击替换视图时,打开您的自定义列表视图弹出窗口! @ntzz 我已经更新了答案。 【参考方案1】:

这是一个关于 Android 和 IOS 中的自定义渲染器的示例。

创建自定义选择器:

public class MyPicker : Picker



Xaml:

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

内容页面:

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 中创建自定义渲染器:

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;
        
    

从渲染器需要custom_picker_dialog.axmlcelllayout.axmlshape_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_
    android:layout_
    android:gravity="center"
    >

     <TextView
        android:text="Select One Option"
        android:layout_
        android:layout_
        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_
      android:dividerHeight="3dp"
      android:layout_
      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_
    android:layout_
    android:gravity="center">


   <TextView
    android:id="@+id/textview1"
    android:layout_
    android:layout_
    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: android:color="#000000"/>

</shape>

最终效果是:

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

IOS:

在 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();
    


最终效果是:

【讨论】:

看起来不错,感谢更新。我最初打算在 xaml 中实现这一点,但据我所知,这是不可能的,所以我需要使用 Android 和 IOS 渲染来实现这些更改。感谢您阐明渲染的工作原理。 @ntzz 感谢您的回复和标记。我也更新了IOS方法。

以上是关于在 Xamarin Forms 中的 Picker 项目上应用样式的主要内容,如果未能解决你的问题,请参考以下文章

Xamarin.Forms.Picker 内容在 UWP 中重复

我们如何处理 Xamarin Forms Picker 的完成按钮单击事件?

Xamarin Forms - 在页面加载时使用异步数据加载 Picker 控件

Xamarin Forms Picker - iOS 上的“完成”文本

Picker.Items 中使用的 Xamarin.Forms 标记扩展

Xamarin.Forms 中 Picker 的自定义渲染器