Как последовательно установить цвет выделенного подчеркивания EditText программным способом

Я пытаюсь создать рендер для Xamarin Forms. Ридеру необходимо установить цвет подчеркивания EditText на "Активный цвет" при выборе и "Цвет подсказки" при отмене выбора. Моя первоначальная настройка выглядит примерно так.

note: здесь путь к полному исходному файлу
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. Затем после этого он переключается между "Цвет подсказки" и "Цвет заполнитель".

note: если я изменил метод SetUnderlineColor на это (ниже), он больше не использует "цвет подсказки" в миксе, но я все равно получаю цвет android:colorAccent в качестве исходного цвета подчеркивания, после чего он ведет себя так, как ожидалось.

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

Что мне нужно сделать, чтобы установить INITIAL выбранный цвет EditText на мой выбранный activeColor/'сфокусированный цвет? (фиолетовый)?

В этой анимации я просто выбираю и снимаю выделение с EditText введите описание изображения здесь

Ответ 1

Итак, решение для меня состояло в чистом AppCompat

Итак, я добавляю AppCompatEditText в TextInputLayout

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);
}

полный исходный код здесь.

Ответ 2

Измените свой код в методе 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
    }
    ...
}

Эффект.

Ответ 3

Почему бы вам не изменить цвет оттенка во время выполнения с помощью этого (может быть, в событии с измененным текстом):

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

В любом случае Goodluck!

Ответ 4

Вам нужно установить backgroundTintList или supportBackgroundTintList в EditText на экземпляр 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>

Пожалуйста, проверьте этот Пример

Надеемся, что это Link1 Link2 поможет вам.

Ответ 5

Чтобы изменить цвет, вы можете использовать ниже код

 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);
            }
        }
    });