Set Placeholder Color of Xamarin’s Picker

In one of my previous post, we’ve discussed about how to adjust font size of Xamarin’s Picker. Font size in picker, especially in Android picker, is simply fixed, so we need a workaround if we want to adjust it. In iOS, font size of the picker is more flexible, you can set height request and width request, or simply put it on a grid, the size of whole picker will follow its container. But there’s another property of picker that also fixed. It’s the placeholder color. I know, most of the time we won’t need to change the placeholder color of the picker. However, for the sake of the app’s theme, sometime we gonna need to set color of the placeholder. So, In case you need it, you can use this method to set the placeholder color.

Custom Picker

To set the placeholder color, first thing we gonna need, of course, a bindable property for it. So we gonna update our CustomPicker from previous post and add Placeholder Color property in it

 

public class CustomPicker : Picker
{
    public static readonly BindableProperty FontSizeProperty =
        BindableProperty.Create(nameof(FontSize), typeof(Int32), typeof(CustomPicker), 24, BindingMode.TwoWay);

    public Int32 FontSize
    {
        set { SetValue(FontSizeProperty, value); }
        get { return (Int32)GetValue(FontSizeProperty); }
    }

    public static BindableProperty PlaceholderColorProperty =
        BindableProperty.Create(nameof(PlaceholderColor), typeof(string), typeof(CustomPicker), "#CCCCCC", BindingMode.TwoWay);

    public string PlaceholderColor
    {
        get { return (string)GetValue(PlaceholderColorProperty); }
        set { SetValue(PlaceholderColorProperty, value); }
    }
}

 

Custom Renderer Android

Next, we update the renderer in Android. In Android, representing the placeholder color, we have property called Hint Text Color. The only problem is Hint Text Color use Color class from Android.Graphic class unlike default Color of Xamarin from Xamarin.Form class. As a result, we need to parse the color. Fortunately, Android.Graphic.Color take hex code as its parameter so we can just simply parse it. The following code is how we do it.

public class CustomPickerRenderer : PickerRenderer
{
    protected override void OnElementChanged(ElementChangedEventArgs e)
    {
        base.OnElementChanged(e);
        this.Control.Background = Forms.Context.GetDrawable(Resource.Drawable.CustomPickerBackground);
        Control?.SetPadding(20, 20, 20, 20);
        if (e.OldElement != null || e.NewElement != null)
        {
            var customPicker = e.NewElement as CustomPicker;
            Control.TextSize *= (customPicker.FontSize * 0.01f);
            Control.SetHintTextColor(Android.Graphics.Color.ParseColor(customPicker.PlaceholderColor));
        }
    }
}

Custom Renderer iOS

Nah, it’s where things got tricky. To set placeholder color, or in iOS term, Foreground Color, we gonna need class named UIColor. And UIColor doesn’t take Hex Code as its parameter. It takes RGB color. Consequently, we need to parse Hex to RGB first. I made three little functions to take the color Red, Green and Blue from our Hex Code.

Finish with the color thing, next we gonna put that color into something, called NSAttributedString. So, what is NSAttributedString? First, Placeholder Attribute in iOS Picker is a NSAttributedString, so we need to make our own NSAttributedString if we want to modify our placeholder. Second, NSAttributedString has many attributes that you’re able to modify. In this example we just use the Foreground Color. but it has many more important attributes such as Background Color , Font, and Stroke Color.

So, this is how the custom renderer in iOS looks like.

public class CustomPickerRenderer: PickerRenderer
{
    protected override void OnElementChanged(ElementChangedEventArgs e)
    {
        base.OnElementChanged(e);
        if (e.OldElement != null || e.NewElement != null)
        {
            var customPicker = e.NewElement as CustomPicker;

            string placeholderColor = customPicker.PlaceholderColor;
            UIColor color = UIColor.FromRGB(GetRed(placeholderColor), GetGreen(placeholderColor), GetBlue(placeholderColor));

            var placeholderAttributes = new NSAttributedString(customPicker.Title,new UIStringAttributes()
            { ForegroundColor = color });

            Control.AttributedPlaceholder = placeholderAttributes;
        }
    }

    private float GetRed(string color)
    {
        Color c = Color.FromHex(color);
        return (float)c.R;
    }

    private float GetGreen(string color)
    {
        Color c = Color.FromHex(color);
        return (float)c.G;
    }

    private float GetBlue(string color)
    {
        Color c = Color.FromHex(color);
        return (float)c.B;
    }
}

Let’s try it out!

I made minor change to example I used in previous post. I add placeholder color and run it in Android and iOS emulator.


    
        
        
        
        
    

 

Sample Code is available in my Github repo.

Advertisements

11 thoughts on “Set Placeholder Color of Xamarin’s Picker

      1. I have added this:
        SelecteurMotif.PlaceholderColor = “#FF0000”; inside a button click, it didn’t work for me even if i add it inside :
        Device.BeginInvokeOnMainThread(() =>
        {
        SelecteurMotif.PlaceholderColor = “#FF0000”;
        });
        But when i add : SelecteurMotif.PlaceholderColor = “#FF0000”; at the beggining in page constractor it works fine.
        Any ideas please ?

        Like

    1. I don’t know it’s gonna work or not, but try put that picker on a container, let say a grid, then after you set color in event, remove and add again that picker from its container. Basically you need to force that property changed to be triggered.

      Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s