如何以编程方式一致地设置 EditText 选定的下划线颜色

How to consistently set EditText Selected Underline Color Programmatically

我正在尝试为 Xamarin Forms 构建渲染器。渲染器需要在选择时将 EditText 下划线颜色设置为 "Active Color",在取消选择时将其设置为 "Hint Color"。我的初始设置看起来像这样。

注意:这里是完整源文件的路径
https://github.com/XamFormsExtended/Xfx.Controls/blob/issue-%236/src/Xfx.Controls.Droid/Renderers/XfxEntryRendererDroid.cs

// called when control is created or when Colors are changed.
protected virtual void SetLabelAndUnderlineColor()
{
    var defaultColor = GetPlaceholderColor();
    var activeColor = GetActivePlaceholderColor();

    SetHintLabelDefaultColor(defaultColor);
    SetHintLabelActiveColor(activeColor);
    SetUnderlineColor(_hasFocus ? activeColor : defaultColor);
}

private void SetUnderlineColor(AColor color)
{
    var bg = ColorStateList.ValueOf(color);
    ViewCompat.SetBackgroundTintList(EditText,bg);
}

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

private void SetHintLabelDefaultColor(AColor color)
{
    var hint = Control.Class.GetDeclaredField("mDefaultTextColor");
    hint.Accessible = true;
    hint.Set(Control, new ColorStateList(new int[][] { new[] { 0 } }, new int[] { color }));
}

除此之外,我还有一个 OnClickListener,它仅在状态改变时才更新下划线

private void ControlOnFocusChange(object sender, FocusChangeEventArgs args)
{
    _hasFocus = args.HasFocus;
    SetUnderlineColor(args.HasFocus ? GetPlaceholderColor() : GetActivePlaceholderColor());
}

问题是,当我点击 EditText 时,对于我将要看到的下划线颜色,它是命中或未命中。 我几乎可以保证第一次使用默认值 android:colorAccent。然后在 "Hint Color" 和 "Placeholder Color".

之间切换

注意:如果我将 SetUnderlineColor 方法更改为此(下),它不再使用混音中的 "Hint Color",但我仍然得到 android:colorAccent 颜色作为初始下划线颜色,之后它的行为符合预期。

private void SetUnderlineColor(AColor color)
{
    var bg = EditText.Background;
    DrawableCompat.SetTint(bg,color);
    EditText.SetBackground(bg);
}

我需要做什么才能将 EditText 的初始选择颜色设置为我选择的 activeColor / 'focused color'(紫色)?

在此动画中,我只是选择和取消选择 EditText

你为什么不在运行时使用这个改变色调颜色(可能在你的文本更改事件中):

ViewCompat.SetBackgroundTintList(_YourView , ColorStateList.ValueOf(Color.ParseColor(Resources.GetString(Resource.Color.blueLine))));

总之祝你好运!

您需要将 EditText 上的 backgroundTintListsupportBackgroundTintList 设置为 ColorStateList

的实例
ColorStateList colorStateList = ColorStateList.valueOf(color)
editText.setSupportBackgroundTintList(colorStateList)

我认为如果你想改变底线颜色,那么你可以使用下面的线来改变

editText.getBackground().mutate().setColorFilter(getResources().getColor(R.color.your_color), PorterDuff.Mode.SRC_ATOP);

应用主题是这样的:-

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>

    <item name="colorControlNormal">@color/colorAccent</item>
    <item name="colorControlActivated">@color/colorAccent</item>
    <item name="colorControlHighlight">@color/colorAccent</item>

</style>

请检查这个Example

希望本文Link1 Link2对您有所帮助。

要更改颜色,您可以使用以下代码

 editText.getBackground().mutate().setColorFilter(your_color), PorterDuff.Mode.SRC_ATOP);

并在焦点更改时为 EditText 视图设置不同颜色的下划线

    editText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
        @Override
        public void onFocusChange(View v, boolean hasFocus) {
            if (hasFocus) {
                editText.getBackground().mutate().setColorFilter(getResources().getColor(android.R.color.holo_purple), PorterDuff.Mode.SRC_ATOP);
            }else {
                editText.getBackground().mutate().setColorFilter(getResources().getColor(android.R.color.holo_red_dark), PorterDuff.Mode.SRC_ATOP);
            }
        }
    });

XfxEntryRendererDroid ControlOnFocusChange 方法中修改您的代码,如下所示:

private void ControlOnFocusChange(object sender, FocusChangeEventArgs args)
{
    _hasFocus = args.HasFocus;
    if (_hasFocus)
    {
        ...   

        EditText.PostDelayed(() =>
            {
                //Add the following code
                SetUnderlineColor(GetActivePlaceholderColor());
                EditText.RequestFocus();
                manager.ShowSoftInput(EditText, 0);
            },
            0);//Change it to 0
    }
    ...
}

Effect.

所以我的解决方案是使用纯 AppCompat

所以我要在 TextInputLayout

中添加一个 AppCompatEditText
protected EditText EditText => Control.EditText;

protected override TextInputLayout CreateNativeControl()
{
    var textInputLayout = new TextInputLayout(Context);
    var editText = new AppCompatEditText(Context)
    {
        SupportBackgroundTintList = ColorStateList.ValueOf(GetPlaceholderColor())
    };
    textInputLayout.AddView(editText);
    return textInputLayout;
}

然后从那里我可以设置与此一致的下划线。

private void ControlOnFocusChange(object sender, FocusChangeEventArgs args)
{
    _hasFocus = args.HasFocus;
    SetUnderlineColor(_hasFocus ?  GetActivePlaceholderColor(): GetPlaceholderColor());
} 

private void SetUnderlineColor(AColor color)
{
    var element = (ITintableBackgroundView)EditText;
    element.SupportBackgroundTintList = ColorStateList.ValueOf(color);
}

full source code here.