TextInpuLayout在未聚焦时提示颜色

时间:2018-01-19 12:20:37

标签: android xml android-layout android-textinputlayout

我正在构建一个自定义TextInputLayout,当设置错误时,提示变为红色。 但它仅在TextInputLayout具有焦点时才有效。在另一场获得焦点后,它再次变为灰色。 这是我的风格:

<style name="ErrorMessage" parent="TextAppearance.AppCompat">
    <item name="android:textColorHint">@color/red</item>
    <item name="android:textColor">@color/red</item>
    <item name="android:textSize">12sp</item>
    <item name="colorAccent">@color/red</item>
    <item name="colorControlNormal">@color/red</item>
    <item name="colorControlActivated">@color/red</item>
</style>

我必须添加任何属性的想法,以便即使在焦点丢失后提示仍保持红色?

编辑: 这是我尝试过的代码(包括Bishoy Abd评论中提出的解决方案): MainActivity

    public class MainActivity extends AppCompatActivity {

    CustomTextInput textInputLayout1;
    CustomTextInput textInputLayout2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        View textInput1Root = findViewById(R.id.text_input_1);
        View textInput2Root = findViewById(R.id.text_input_2);

        TextInputLayout textInput1 = textInput1Root.findViewById(R.id.label);
        TextInputLayout textInput2 = textInput2Root.findViewById(R.id.label);

        textInput1.setHint("Edit Text 1");
        textInput2.setHint("Edit Text 2");

        textInputLayout1 = new CustomTextInput(this, textInput1Root);
        textInputLayout2 = new CustomTextInput(this, textInput2Root);

        AppCompatButton validateButton = findViewById(R.id.validate_button);
        validateButton.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                validateFields();
            }
        });

        textInput1Root.findViewById(R.id.edit_text).setOnFocusChangeListener(new View.OnFocusChangeListener() {
            @Override
            public void onFocusChange(View v, boolean hasFocus) {
                if (!hasFocus) {
                    validate(((EditText) v).getText().toString());
                }
            }
        });

        textInput2Root.findViewById(R.id.edit_text).setOnFocusChangeListener(new View.OnFocusChangeListener() {
            @Override
            public void onFocusChange(View v, boolean hasFocus) {
                if (!hasFocus) {
                    validate(((EditText) v).getText().toString());
                }
            }
        });
    }

    private void validate(String txt) {
        if (!TextUtils.isEmpty(txt)) {
            textInputLayout1.hideErrorMessage();
        } else {
            textInputLayout1.setErrorMessage("Invalid");
            textInputLayout1.showErrorMessage();
        }
    }

    private void validateFields() {
        if (!isFieldValid(findViewById(R.id.text_input_1))) {
            textInputLayout1.setErrorMessage("Invalid");
            textInputLayout1.showErrorMessage();
        } else {
            textInputLayout1.hideErrorMessage();
        }
        if (!isFieldValid(findViewById(R.id.text_input_2))) {
            textInputLayout2.setErrorMessage("Invalid");
            textInputLayout2.showErrorMessage();
        } else {
            textInputLayout1.hideErrorMessage();
        }
    }

    private boolean isFieldValid(View inputField) {
        TextInputLayout input = inputField.findViewById(R.id.label);
        EditText editText = inputField.findViewById(R.id.edit_text);
        if (editText.getText() == null || editText.getText().toString().trim().equals("")) {
            return false;
        }
        return true;
    }
}

CustomTextInput

  public class CustomTextInput extends LinearLayout {

    private String errorMessage;
    private final String defaultErrorMessage = "ERROR_MESSAGE_NOT_SET";
    //Children:
    private TextInputLayout textInputLayout;
    private AppCompatEditText appComaptEditText;


    public CustomTextInput(Context context, @Nullable AttributeSet attrs) {
        this(context);
    }

    public CustomTextInput(Context context, View rootView) {
        this(context);
        errorMessage = defaultErrorMessage;
        if (rootView != null) {
            textInputLayout = rootView.findViewById(R.id.label);
            appComaptEditText = rootView.findViewById(R.id.edit_text);
        }
    }

    public CustomTextInput(Context context) {
        super(context);
    }

    public void showErrorMessage() {
        textInputLayout.setHintTextAppearance(R.style.ErrorMessage);
        textInputLayout.setErrorEnabled(true);
        textInputLayout.setError(errorMessage);
    }

    public EditText getEditText() {
        return appComaptEditText;
    }

    public TextInputLayout getLabel() {
        return textInputLayout;
    }

    public void hideErrorMessage() {
        textInputLayout.setHintTextAppearance(R.style.Hint);
        textInputLayout.setError(null);
        textInputLayout.setErrorEnabled(false);
    }

    public void setErrorMessage(String message) {
        errorMessage = message;
    }

    public void setHint(String hint) {
        textInputLayout.setHint(hint);
    }
}

colors.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#3F51B5</color>
    <color name="colorPrimaryDark">#303F9F</color>
    <color name="colorAccent">#FF4081</color>
    <color name="red">#ff0011</color>
    <color name="black">#000000</color>
</resources>

The `styles.xml`:

    <resources>

    <!-- Base application theme. -->
    <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>
    </style>

    <style name="Hint" parent="TextAppearance.AppCompat">
        <item name="android:textColor">@color/black</item>
        <item name="android:textSize">12sp</item>
        <item name="colorAccent">@color/colorPrimary</item>
        <item name="colorControlNormal">@color/black</item>
        <item name="colorControlActivated">@color/colorPrimary</item>
        <item name="colorControlHighlight">@color/colorPrimary</item>
    </style>

    <style name="ErrorMessage" parent="TextAppearance.AppCompat">
        <item name="android:textColorHint">@color/red</item>
        <item name="android:textColor">@color/red</item>
        <item name="android:textSize">12sp</item>
        <item name="colorAccent">@color/red</item>
    </style>

</resources>

custom_text_input.xml

<?xml version="1.0" encoding="utf-8"?>
<test.textinputlayouterrortest.CustomTextInput
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/app_text_input"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:focusableInTouchMode="true"
    android:orientation="vertical">

    <android.support.design.widget.TextInputLayout
        android:id="@+id/label"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom"
        android:paddingTop="16dp"
        app:errorTextAppearance="@style/ErrorMessage"
        app:hintTextAppearance="@style/Hint">

        <android.support.v7.widget.AppCompatEditText
            android:id="@+id/edit_text"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:paddingBottom="8dp"
            android:paddingTop="8dp"/>
    </android.support.design.widget.TextInputLayout>
</test.textinputlayouterrortest.CustomTextInput>

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="test.textinputlayouterrortest.MainActivity">

    <include
        android:id="@+id/text_input_1"
        layout="@layout/custom_text_input"/>

    <include
        android:id="@+id/text_input_2"
        layout="@layout/custom_text_input"/>

    <android.support.v7.widget.AppCompatButton
        android:id="@+id/validate_button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="validate"
        android:textAllCaps="true"/>

</LinearLayout>

2 个答案:

答案 0 :(得分:0)

XML(abc.xml)选择器,用于设置不同状态下标签的颜色

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto">
    <item android:color="@color/red" android:state_focused="true" />
    <item android:color="@color/red" android:state_focused="false" />
    <item android:color="@color/select_your_color" app:state_empty_text="true"/>
    <item android:color="@color/select_your_color"/> <!-- default color -->
</selector>

现在在res / values / styles.xml中定义edittext样式:

<style name="EditTextLayout">

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

现在将此样式应用于您的edittext并根据颜色更改颜色。

答案 1 :(得分:-1)

假设您在TextInputLayout s中使用了两个EdtitText passwordEt,userNameEt

passwordEt.setOnFocusChangeListener(new View.OnFocusChangeListener() {
            @Override
            public void onFocusChange(View v, boolean hasFocus) {
                if (!hasFocus) {
                    validatePassword(((EditText) v).getText().toString());
                }
            }
        });

userNameEt.setOnFocusChangeListener(new View.OnFocusChangeListener() {
            @Override
            public void onFocusChange(View v, boolean hasFocus) {
                if (!hasFocus) {
                    validateUserName(((EditText) v).getText().toString());
                }
            }
        });

 private void validatePassword(String pass) {
    if (!TextUtils.isEmpty(pass)) {
        textInputLayoutPassword.setError(null);
    }
    else{
        textInputLayoutPassword.setError(getString(R.string.password_error));
    }
}

同样适用于userNameEt和其他EditText s