Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to change the colour of the line below / Border of a TextBox (Entry)

I am creating a Xamarin.Forms application on Android and I am trying to change the colour of the line below my Xamarin.Forms Entry control.

I have an Entry control like so:

<Entry Text="new cool street"/>

enter image description here

I would like to change the colour of the line below this Entry from the default white to more of a purple to match my theme.

Idealy it would be better to do using Android Styles as it would apply to all controls inheriting from Entry if possible

Is this possible to do?

like image 890
User1 Avatar asked Jul 05 '16 15:07

User1


4 Answers

you can use custom renderer that will affect all entries,

here's for android:

[assembly: ExportRenderer(typeof(Entry), typeof(MyEntryRenderer))]
namespace Android.MyRenderers
{
    public class MyEntryRenderer : EntryRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
        {
            base.OnElementChanged(e);

            if (Control == null || e.NewElement == null) return;

            if (Build.VERSION.SdkInt >= BuildVersionCodes.Lollipop)
                Control.BackgroundTintList = ColorStateList.ValueOf(Color.White);
            else
                Control.Background.SetColorFilter(Color.White, PorterDuff.Mode.SrcAtop);
         }    
    }
}

and iOS:

[assembly: ExportRenderer (typeof(Entry), typeof(MyEntryRenderer))]
namespace iOS.MyRenderers
{
    public class MyEntryRenderer : EntryRenderer
    {
        private CALayer _line;

        protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
        {
            base.OnElementChanged (e);
            _line = null;

            if (Control == null || e.NewElement == null)
                return;

            Control.BorderStyle = UITextBorderStyle.None;

            _line = new CALayer {
                BorderColor = UIColor.FromRGB(174, 174, 174).CGColor,
                BackgroundColor = UIColor.FromRGB(174, 174, 174).CGColor,
                Frame = new CGRect (0, Frame.Height / 2, Frame.Width * 2, 1f)
            };

            Control.Layer.AddSublayer (_line);
        }
    }
}

not sure about Windows solution on this

like image 73
root Avatar answered Oct 17 '22 01:10

root


I had the same problem and just changing the colorAccent value in styles.xml (in Xamarin.Android project) will change the colour of the cursor and the bottom border of an Entry field.

<item name="colorAccent">#BA55D3</item>
like image 35
Curiousity Avatar answered Oct 17 '22 02:10

Curiousity


Since I have the content pages with one background color and dialogs with another, using Styles to specify the bottom bar color is totally the wrong answer. And since the OP only asked about Android, this is just Android...

I use a custom renderer to set the bottom bar color the same as the text color. Have to both ElementChanged and PropertyChanged.

[assembly: ExportRenderer(typeof(Xamarin.Forms.Entry), typeof(CustomEntryRenderer))]
namespace XamFormsConnect.Droid
{
    public class CustomEntryRenderer : EntryRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.Entry> e)
        {
            base.OnElementChanged(e);

            if (Control != null && e.NewElement != null)
            {
                var entry = (Xamarin.Forms.Entry)e.NewElement;
                if (Build.VERSION.SdkInt >= BuildVersionCodes.Lollipop)
                    Control.BackgroundTintList = ColorStateList.ValueOf(entry.TextColor.ToAndroid());
                else
                    Control.Background.SetColorFilter(entry.TextColor.ToAndroid(), PorterDuff.Mode.SrcAtop);
            }
        }

        protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            base.OnElementPropertyChanged(sender, e);

            if (e.PropertyName == "TextColor")
            {
                var entry = (Xamarin.Forms.Entry)sender;
                if (Build.VERSION.SdkInt >= BuildVersionCodes.Lollipop)
                    Control.BackgroundTintList = ColorStateList.ValueOf(entry.TextColor.ToAndroid());
                else
                    Control.Background.SetColorFilter(entry.TextColor.ToAndroid(), PorterDuff.Mode.SrcAtop);
            }
        }
    }
}
like image 10
djunod Avatar answered Oct 17 '22 02:10

djunod


UPDATE : Xamarin.Forms 2.5

I've trying the top rated solution and an error occurs : “Context is obsolete as of version 2.5. Please use a local context instead”.

After some quick search :

  • Xamarin.Forms 2.5.0 and Context
  • https://forums.xamarin.com/discussion/106938/context-is-obsolete-as-of-version-2-5

The code need to be updated :

using <YOUR_APP_NAME>.Droid;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
using Android.Content;
using Android.OS;
using Android.Content.Res;
using Android.Graphics;

[assembly: ExportRenderer(typeof(Entry), typeof(MyRenderers))]
namespace Android.MyRenderers
{
    public class MyRenderers : EntryRenderer
    {

        public MyRenderers(Context context) : base(Android.App.Application.Context)
        {

        }
        protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
        {
            base.OnElementChanged(e);

            if (Control == null || e.NewElement == null) return;

            if (Build.VERSION.SdkInt >= BuildVersionCodes.Lollipop)
                Control.BackgroundTintList = ColorStateList.ValueOf(Android.Graphics.Color.Ivory);
            else
                Control.Background.SetColorFilter(Android.Graphics.Color.Ivory, PorterDuff.Mode.SrcAtop);
        }
    }
}

For who need the update.

like image 4
PaulCrp Avatar answered Oct 17 '22 00:10

PaulCrp