编程设置TextInputLayout提示文本颜色和浮动标签颜色

22

我正在使用一个TextInputLayout,如果输入字段是必填项,我希望能以编程方式设置提示文本颜色和浮动标签颜色。在采用TextInputLayout之前,我通常使用以下方法以编程方式设置提示文本颜色:

textField.setHintTextColor(Color.RED);

有人可以指导我如何通过编程设置TextInputLayout的提示文本颜色和浮动标签颜色吗?

在附加的屏幕截图中,当输入框未被聚焦时,我希望提示文本地址1呈现为红色,而在聚焦后,浮动标签地址1应该呈现为红色。

enter image description here


你可以为这些文本字段添加一个 **OnFocusChangeListener**。我不知道它是否有效。 - wngxao
在编辑文本中添加一个onFocusChangeListener,并更改提示颜色。onFocusChangeListener在其参数中提供一个布尔值,如果编辑文本具有焦点,则为true,当焦点被移出时为false。相应地设置hintTextColor。 - Shashank Udupa
我没有尝试过,但我认为这对你应该有效:InputTextLayout.getEditText().setHintTextColor(Color.RED); - Stanojkovic
@Stanojkovic 尝试了这个,但不起作用。 - S.A.Norton Stanley
8个回答

21

我使用反射改变了聚焦颜色。以下是代码片段,希望对某些人有所帮助。

private void setUpperHintColor(int color) {
    try {
        Field field = textInputLayout.getClass().getDeclaredField("mFocusedTextColor");
        field.setAccessible(true);
        int[][] states = new int[][]{
                new int[]{}
        };
        int[] colors = new int[]{
                color
        };
        ColorStateList myList = new ColorStateList(states, colors);
        field.set(textInputLayout, myList);

        Method method = textInputLayout.getClass().getDeclaredMethod("updateLabelState", boolean.class);
        method.setAccessible(true);
        method.invoke(textInputLayout, true);

    } catch (Exception e) {
        e.printStackTrace();
    }
}

编辑 2018-08-01:

如果您正在使用设计库v28.0.0及更高版本,则字段已从mDefaultTextColor更改为defaultHintTextColor,并且从mFocusedTextColor更改为focusedTextColor

检查反编译类以获取其他字段。


1
你太棒了,伙计。如果你知道我花了多少时间来寻找解决方案! - Hesam
谢谢,但我不太建议使用这种方法。 - alexandrius
1
我知道你为什么不推荐,但我没有找到一种正常的方式使用Android方法来动态地改变颜色。你有任何想法吗?谢谢。 - Hesam
我建议创建自己的InputLayout。这就是我所做的。 - alexandrius
2
请注意,自2019年1月9日起,已进行以下更改:
  • mFocusedTextColor 更改为 focusedTextColor
  • mDefaultTextColor 更改为 defaultHintTextColor
  • mCollapsingTextHelper 更改为 collapsingTextHelper
  • mCollapsedTypeface 更改为 collapsedTypeface
- Cheok Yan Cheng
显示剩余2条评论

17

使用Material Components库,您可以使用以下功能:

在布局中:

<com.google.android.material.textfield.TextInputLayout
    app:hintTextColor="@color/mycolor"
    android:textColorHint="@color/text_input_hint_selector"
    .../>

以一种风格:

<style name="..." parent="Widget.MaterialComponents.TextInputLayout.FilledBox">
    <!-- The color of the label when it is collapsed and the text field is active -->
    <item name="hintTextColor">?attr/colorPrimary</item>
    <!-- The color of the label in all other text field states (such as resting and disabled) -->
    <item name="android:textColorHint">@color/mtrl_indicator_text_color</item>
</style>

在代码中:

// Sets the text color used by the hint in both the collapsed and expanded states
textInputLayout.setDefaultHintTextColor(...);

//Sets the collapsed hint text color
textInputLayout.setHintTextColor(....);

请使用此代码为TextInputLayout添加材料设计。 - Muhammad Irfan

7
请仔细查看此处的文档:TextInputLayout方法 其中有一个方法:
setHintTextAppearance(int resId)

这里需要一个资源ID,可以是样式资源!

我会尝试一下,看看效果如何!

希望能对你有所帮助!


尝试了以下代码:如果(isMandatory()){ textInputLayout.setHintTextAppearance(Color.RED); } 仍然没有运行。isMandatory() 是一个指示字段是否强制输入的方法 :-( - S.A.Norton Stanley
1
尝试这个答案 https://dev59.com/6VsX5IYBdhLWcg3whvwn?rq=1 - Eenvincible
那对我也不起作用。我尝试了textInputLayout.setErrorEnabled(true);textInputLayout.setError(" ");。现在这会以红色显示浮动标签,但是没有提示文本出现。为了完整性,我将此发布为答案。 - S.A.Norton Stanley
好的!很高兴你得到了更接近你想要的东西。 - Eenvincible
预期的资源类型是样式而不是颜色。在发布自己的描述之前,请确保阅读方法。 - Bhavik Mehta

4
通常TextInputLayout的提示文本颜色来自于应用程序的colorAccent颜色。但是如果您想要更改它,可以使用样式进行修改。
<android.support.design.widget.TextInputLayout
     android:layout_width="fill_parent"
     android:layout_height="wrap_content"
     android:theme="@style/TextLabel">
 </android.support.design.widget.TextInputLayout>

@style

<style name="TextLabel" parent="TextAppearance.AppCompat">
    <!-- Hint color and label color in FALSE state -->
    <item name="android:textColorHint">@color/Color Name</item> 
    <item name="android:textSize">20sp</item>
    <!-- Label color in TRUE state and bar color FALSE and TRUE State -->
    <item name="colorAccent">@color/Color Name</item>
    <item name="colorControlNormal">@color/Color Name</item>
    <item name="colorControlActivated">@color/Color Name</item>
 </style>

但是如果您想添加红色,则如何与错误颜色区分,这意味着基本标准错误具有红色。

textField.setHintTextColor(Color.RED); 有人可以指导我如何通过编程方式设置TextInputLayout的提示文本颜色和浮动标签颜色。

setHintTextColor适用于API 23及以上版本。


3

要更改TextInput布局的聚焦颜色默认文本颜色,请按以下步骤操作:

private void setInputTextLayoutColor(int color, TextInputLayout textInputLayout) {
    try {
        Field field = textInputLayout.getClass().getDeclaredField("mFocusedTextColor");
        field.setAccessible(true);
        int[][] states = new int[][]{
                new int[]{}
        };
        int[] colors = new int[]{
                color
        };
        ColorStateList myList = new ColorStateList(states, colors);
        field.set(textInputLayout, myList);

        Field fDefaultTextColor = TextInputLayout.class.getDeclaredField("mDefaultTextColor");
        fDefaultTextColor.setAccessible(true);
        fDefaultTextColor.set(textInputLayout, myList);

        Method method = textInputLayout.getClass().getDeclaredMethod("updateLabelState", boolean.class);
        method.setAccessible(true);
        method.invoke(textInputLayout, true);

    } catch (Exception e) {
        e.printStackTrace();
    }
}

编辑:修改AppCompactEditText的线条颜色

您需要在EditText上设置backgroundTintList(或supportBackgroundTintList)为一个ColorStateList实例,该实例只包含您希望更改着色的颜色。以下是一种向后兼容的简单方法:

ColorStateList colorStateList = ColorStateList.valueOf(color)
editText.setSupportBackgroundTintList(colorStateList)

这将为EditText提供所需的下划线颜色。


1
感谢提供mDefaultTextColor。如果我们决定更改浮动文本颜色,即使EditText被禁用,也是必需的。 - Cheok Yan Cheng

1

我曾经遇到过类似的问题,但是涉及可变提示和彩色符号。我通过数据绑定和Spannable技巧解决了这个问题。

 <com.google.android.material.textfield.TextInputLayout
                android:id="@+id/ti_last_name"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginStart="8dp"
                android:layout_marginTop="4dp"
                android:layout_marginEnd="8dp"
                app:boxStrokeWidth="0dp"
                app:boxStrokeWidthFocused="0dp"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintHorizontal_bias="0.5"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent">

                <com.google.android.material.textfield.TextInputEditText
                    android:id="@+id/et_last_name"
                    style="@style/EditText"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    app:onFocusChangeListener="@{viewModel.onFocusChangeListener(@string/last_name)}"
                    tools:hint="@string/last_name" />
</com.google.android.material.textfield.TextInputLayout>

以这种方式定义的viewModel.onFocusChangeListener

    fun onFocusChangeListener(hint: String) =
        OnFocusChangeListener { view, isFocused ->
            (view.parent.parent as TextInputLayout).apply {
                val editText = (view as TextInputEditText)
                if (isFocused) {
                    this.hintTextColor = ColorStateList.valueOf(this.getColor(R.color.black))
                    editText.hint = ""
                    this.hint = hint
                } else {
                    if (!editText.text.isNullOrBlank()) {
                        this.defaultHintTextColor = ColorStateList.valueOf(this.getColor(R.color.black))
                        editText.hint = ""
                        this.hint = hint
                    } else {
                        this.hintTextColor = ColorStateList.valueOf(this.getColor(R.color.hint_color))
                        val builder = SpannableStringBuilder()
                        builder.append(hint)
                        val start = builder.length
                        val end = start + 1
                        builder.append("\u2981")
                        builder.setSpan(
                            ForegroundColorSpan(Color.RED),
                            start,
                            end,
                            Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
                        )
                        builder.setSpan(
                            SuperscriptSpan(),
                            start,
                            end,
                            Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
                        )
                        editText.hint = builder
                        this.hint = ""
                    }
                }
            }

        }

允许为聚焦/非聚焦状态使用不同的提示和颜色,并具有带颜色的跨度。

this.getColor()只是一个扩展

 fun View.getColor(color: Int): Int {
    return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        this.context.resources.getColor(color, context.theme)
    } else {
        this.context.resources.getColor(color)
    }

0

让我分享一下我的经验。我也尝试了所有与此相关的问题中提供的解决方案,即更改子小部件的提示颜色为TextInputLayout

我很高兴能够详细地回答这个问题。

我们需要知道的是:

  1. 将以下行添加到TextInputLayout或其子小部件的样式中并没有多大帮助。

    <item name="android:textColorHint">@color/white</item>

    因为每当焦点接收/授予可编辑小部件时,它都会使用colorAccent。

  2. 这个问题的真正答案是在应用程序的样式标签中添加该样式行,这样当那个或任何可编辑区域不处于焦点状态时,它将设置提示颜色。(这是我们每次都错过的关键点)。

如果我们有其他信息,请告诉我。

谢谢!


-5

我使用以下方法成功将FloatingLabel设置为红色

textInputLayout.setErrorEnabled(true);
textInputLayout.setError(" ");

enter image description here


1
这只是一种强制 TextInputLayout 外观作为错误文本的解决方法。@alexandrius 的答案应该被接受。 - Vikas Patidar
好的,这解决了我的问题,因此被接受为答案! - S.A.Norton Stanley
这不是解决方案。 - Ananta Prasad

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接