首页 > 解决方案 > Xamarin Forms and Material design,如何更改提示颜色

问题描述

我尝试为 Xamarin Forms 创建一个 Material Design 条目,但提示颜色和底线有问题。

编辑York Shen回答:

Xaml 页面

<customControls:CustomEntry
    Keyboard="Email"
    Placeholder="EMAIL"
    Style="{StaticResource EntryAccount}"
    Text="{Binding Email}" />

EntryAccount 风格

<Style x:Key="EntryAccount" TargetType="customControls:CustomEntry">
    <Setter Property="PlaceholderColor" Value="{StaticResource BackgroundColor}" />
    <Setter Property="BottomLineColor" Value="{StaticResource BackgroundColor}" />
    <Setter Property="TextColor" Value="{StaticResource BackgroundColor}" />
    <Setter Property="FontSize" Value="{StaticResource Subtitle1}" />
    <Setter Property="FontFamily" Value="{StaticResource Subtitle1Font}" />
</Style>

自定义条目

public class CustomEntry : Entry
{
    public static readonly BindableProperty BottomLineColorProperty =
        BindableProperty.Create(nameof(BottomLineColor), typeof(Color), typeof(CustomEntry), Color.Blue);

    public Color BottomLineColor
    {
        get => (Color) GetValue(BottomLineColorProperty);
        set => SetValue(BottomLineColorProperty, value);
    }
}

CustomEntryRenderer

public class CustomEntryRenderer : Xamarin.Forms.Platform.Android.AppCompat.ViewRenderer<CustomEntry, TextInputLayout>
{
    public CustomEntryRenderer(Context context) : base(context)
    {
    }

    protected EditText EditText => Control.EditText;

    protected override TextInputLayout CreateNativeControl()
    {
        var textInputLayout = new TextInputLayout(Context);
        var editText = new AppCompatEditText(Context);
        editText.SetTextSize(ComplexUnitType.Sp, (float) Element.FontSize);
        textInputLayout.AddView(editText);
        return textInputLayout;
    }

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

        if (e.NewElement != null)
        {
            var ctrl = CreateNativeControl();
            SetNativeControl(ctrl);

            var activeColor = Element.BottomLineColor.ToAndroid(global::Android.Resource.Attribute.ColorAccent, Context);

            var hintText = Control.Class.GetDeclaredField("mFocusedTextColor");
            hintText.Accessible = true;
            hintText.Set(Control, new ColorStateList(new int[][] {new[] {0}}, new int[] {activeColor}));

            EditText.Enabled = Element.IsEnabled;
            Control.Hint = Element.Placeholder;
            EditText.SetTextColor(Element.TextColor.ToAndroid());
        }
    }
}

Element.TextColor & activeColor正确获取我在参数中传递的颜色。

但这是我的结果:

1

2

标签: c#androidxamarin.formseditor

解决方案


Xamarin Forms and Material design,如何更改提示颜色

您可以添加AppCompatEditText一个TextInputLayout

protected EditText EditText => Control.EditText;

protected override TextInputLayout CreateNativeControl()
{
    var textInputLayout = new TextInputLayout(Context);
    var editText = new AppCompatEditText(Context);
    editText.SetTextSize(ComplexUnitType.Sp, (float)Element.FontSize);
    textInputLayout.AddView(editText);
    return textInputLayout;
}

然后像这样设置提示文本颜色:

var activeColor = Element.ActiveHintTextColor.ToAndroid(global::Android.Resource.Attribute.ColorAccent, Context);
var hintText = Control.Class.GetDeclaredField("mFocusedTextColor");
hintText.Accessible = true;
hintText.Set(Control, new ColorStateList(new int[][] { new[] { 0 } }, new int[] { activeColor }));

源代码

自定义条目:

public class CustomEntry : Entry
{
    public static readonly BindableProperty ActiveHintTextColorProperty = BindableProperty.Create(nameof(ActiveHintTextColor),
       typeof(Color),
       typeof(CustomEntry),
       Color.Accent);

    /// <summary>
    /// ActiveHintTextColor summary. This is a bindable property.
    /// </summary>
    public Color ActiveHintTextColor
    {
        get { return (Color)GetValue(ActiveHintTextColorProperty); }
        set { SetValue(ActiveHintTextColorProperty, value); }
    }
}

渲染器:

public class CustomEntryRenderer : Xamarin.Forms.Platform.Android.AppCompat.ViewRenderer<CustomEntry, TextInputLayout>
{
    public CustomEntryRenderer (Context context) : base(context)
    {
    }

    protected EditText EditText => Control.EditText;

    protected override TextInputLayout CreateNativeControl()
    {
        var textInputLayout = new TextInputLayout(Context);
        var editText = new AppCompatEditText(Context);
        editText.SetTextSize(ComplexUnitType.Sp, (float)Element.FontSize);
        textInputLayout.AddView(editText);
        return textInputLayout;
    }

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

        if (e.NewElement != null)
        {
            var ctrl = CreateNativeControl();
            SetNativeControl(ctrl);

            var activeColor = Element.ActiveHintTextColor.ToAndroid(global::Android.Resource.Attribute.ColorAccent, Context);

            var hintText = Control.Class.GetDeclaredField("mFocusedTextColor");
            hintText.Accessible = true;
            hintText.Set(Control, new ColorStateList(new int[][] { new[] { 0 } }, new int[] { activeColor }));

            EditText.Enabled = Element.IsEnabled;
            Control.Hint = Element.Placeholder;
            EditText.SetTextColor(Element.TextColor.ToAndroid());
        }
    }
}

用法:

<local:CustomEntry
    Placeholder="Enter your name:"
    Text="Name"
    ActiveHintTextColor="Blue"
    PlaceholderColor="Black"
        />

影响

更新:

设置底线颜色:

var element = (ITintableBackgroundView)EditText;
//using AColor = Android.Graphics.Color;
element.SupportBackgroundTintList = ColorStateList.ValueOf(AColor.White);

推荐阅读