Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can anyone come up with a Custom Renderer solution to change the color of the underline in Android?

I have a Xamarin forms application that uses this code:

<Grid
    HeightRequest="50"
    VerticalOptions="CenterAndExpand"
    x:Class="J.Templates.EntryGrid"
    x:Name="this"
    xmlns ="http://xamarin.com/schemas/2014/form
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" >
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto"/>
        <ColumnDefinition Width="*"/>
        <ColumnDefinition x:Name="lastColumnWidth" Width="150"/>
    </Grid.ColumnDefinitions>
    <Label Grid.Column="0" Text="{Binding Text1, Source={x:Reference this}}"  />
    <Entry Grid.Column="1"
               HorizontalOptions="FillAndExpand"
               HorizontalTextAlignment="End"
               VerticalOptions="FillAndExpand"
               TextColor="{DynamicResource LabelLinkColor}"
               Keyboard="{Binding EntryKeyboardType,  Source={x:Reference this}}"
               Text="{Binding EntryText,  Source={x:Reference this}}"
               FontSize="{DynamicResource LabelTextFontSize}"
               FontFamily="{DynamicResource DefaultFont}"
               BackgroundColor="Transparent"
    </Entry>
</Grid>

The iOS and Android views look like this:

enter image description here

Is there any way I can change the Android underline color and also (if possible) spacing of the gap between the underline and the numbers.

like image 344
Alan2 Avatar asked Jun 18 '20 08:06

Alan2


People also ask

What is a custom renderer?

Building a custom renderer is an advanced pattern that leverages the autocomplete-core package to fully control the rendered experience. You shouldn't need to use it unless you've reached limitations with autocomplete-js and it's templating capabilities.

How do I change the entry cursor color in xamarin?

Step 1: Create a custom entry control, since we do not have a direct support to achieve this requirement. Step 2: Add the custom entry control as InputView in the TextInputLayout. Step 3: Create a custom renderer and set the desired color using the platform specific property.


1 Answers

If you wish to remove the underline, then you have to do it in a Custom Renderer.

[assembly: ExportRenderer(typeof(Entry), typeof(CustomEntryRenderer))]
namespace CustomEntryUnderline.Android
{
    public class CustomEntryRenderer : EntryRenderer
    {
        public CustomEntryRenderer(Context context)
            : base(context)
        {
        }

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

            if (Control != null)
            {
                Control.Background = null;
            }
        }
    }
}

If you wish to change the underline color, you have to create a Color state list resource.

In the Android project, under Resources folder, create a new directory Color. In it, create a xml file, describing the selector drawable. Let's call it editable_selector.xml. Here's how it will look like:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true" android:color="#00ff00"/>
    <item android:state_focused="true" android:color="#ff0000"/>
    <item android:state_active="false" android:color="#0000ff"/>
</selector>

Here, you can change a lot of things, but in the xml selector, I have set the border to be blue by default, green when pressed and red when focused.

Then in your renderer, you'll have to set the native view's BackgroundTintList. We'll be doing this again in the OnElementChanged method.

protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{
    base.OnElementChanged(e);
    if (Control != null)
    {
        var colorStateList = Context.GetColorStateList(Resource.Color.editable_selector);
        Control.BackgroundTintList = colorStateList;
    }
}

Here's a running gif:

enter image description here

You don't need to change the "gap", just adjust your layout, because currently the issue is not with the default offset, but with the way the layout is being rendered. Changing the offset should be considered a last resort.

However, if you still want to change the bottom padding between the text and the bottom border, again, in the OnElementChanged method, set the Control's padding like this:

Control.SetPadding(0, 0, 0, 120);

Here, I have set only a bottom padding of 120.

NB: It is not considered a good approach to create a renderer that will override all elements. Here, for simplicity, I am exporting the renderers for the built-in Entry type. It is better to wrap the Entry inside your own CustomEntry class in order to not modify the styles globally.

like image 119
Mihail Duchev Avatar answered Sep 28 '22 07:09

Mihail Duchev