Reputation: 559
I want the floating label of TextInputLayouts to change colour (e.g. to red) when there is an error. I can change the colour of the error text, but it has no effect on the appearance of the floating label (unlike someone in some other thread claimed). I couldn't use selectors for the hint colour to solve this problem either, as there does not seem to be a state defined for errors. Does anyone have any idea how to do this without having to manually program the change on error events/create a new java class (with EditText as parent)?
Here are the stylings I defined:
<style name="EditTextFloatingLabel" parent="@android:style/TextAppearance">
<item name="android:textSize">@dimen/textsize_caption_small</item>
<item name="android:layout_marginBottom">8dp</item>
<item name="android:textColor">@color/input_text_color</item>
</style>
<style name="EditTextErrorText" parent="@android:style/TextAppearance">
<item name="android:textColor">@color/error_color</item>
</style>
<style name="EditTextLayout">
<item name="android:textColorHint">@color/placeholder_color</item>
<item name="android:background">@drawable/input_field_background</item>
<item name="android:paddingBottom">@dimen/default_margin_bottom</item>
<item name="android:paddingStart">@dimen/default_margin_left</item>
<item name="android:paddingEnd">@dimen/default_margin_right</item>
</style>
<style name="EditTextTheme">
<item name="android:imeOptions">actionDone</item>
<item name="android:maxLines">1</item>
<item name="colorControlNormal">@color/primary_line_color</item>
<item name="colorControlActivated">@color/nordea_blue</item>
<item name="android:colorControlHighlight">@color/error_color</item>
<item name="android:textColorPrimary">@color/input_field_text</item>
<item name="android:textSize">@dimen/textsize_caption</item>
<item name="android:textColorHint">@color/placeholder_color</item>
</style>
<style name="EditText">
<item name="android:theme">@style/EditTextTheme</item>
<item name="android:textCursorDrawable">@drawable/cursor_blue</item>
<item name="android:paddingTop">@dimen/default_padding_top</item>
<item name="android:paddingStart">@dimen/payment_text_input_padding</item>
</style>
Usage:
<android.support.design.widget.TextInputLayout
android:id="@+id/input_field_error_wrapper_light"
style="@style/EditTextLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/testlogin_text_input_end_padding"
android:layout_marginStart="@dimen/testlogin_text_input_start_padding"
android:paddingTop="@dimen/default_padding_top"
app:hintTextAppearance="@style/EditTextFloatingLabel"
app:errorTextAppearance="@style/EditTextErrorText"
app:errorEnabled="true">
<EditText
android:id="@+id/input_field_light_error"
style="@style/EditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#Input Field Disabled Light"
android:imeOptions="actionDone"
/>
</android.support.design.widget.TextInputLayout>
And this is what I see:
Upvotes: 3
Views: 1724
Reputation: 559
As I needed to perform some other actions as well when the layout was in error state, I decided to go with the solution of creating a custom error state and a custom TextInputLayout which can enter this state.
Code:
Defining the new error state in res/values/attrs.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
...
<!-- custom states -->
<declare-styleable name="ErrorState">
<attr name="state_error" format="boolean" />
</declare-styleable>
</resources>
ErrorStateTextInputLayout class:
public class ErrorStateTextInputLayout extends TextInputLayout {
private boolean hasError = false;
private static final int[] ERROR_STATE = new int[]{R.attr.state_error};
public ErrorStateTextInputLayout(Context context) {
super(context);
}
public ErrorStateTextInputLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ErrorStateTextInputLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected int[] onCreateDrawableState(int extraSpace) {
int[] state = super.onCreateDrawableState(extraSpace + 1);
if (hasError) {
mergeDrawableStates(state, ERROR_STATE);
}
return state;
}
@Override
public void setError(@Nullable CharSequence error) {
if (error == null) {
setHasError(false);
} else {
setHasError(true);
}
super.setError(error);
}
public void setHasError(boolean error) {
this.hasError = error;
refreshDrawableState();
}
}
Selector for setting the hint text colour:
<?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/disabled_text_color" android:state_enabled="false" />
<item android:color="@color/error_color" app:state_error="true" />
<item android:color="@color/input_text_color" android:state_focused="true" />
<item android:color="@color/placeholder_color" />
</selector>
This blog post helped me a lot: http://code.neenbedankt.com/example-of-custom-states-in-android-components/
Upvotes: 3
Reputation: 4182
Try this..solid_red floating color.....
<style name="TextLabelInput" parent="TextAppearance.AppCompat">
<!-- Hint color and label color in FALSE state -->
<item name="android:textColorHint">@color/solid_red</item>
<item name="android:textSize">16sp</item>
<item name="android:textStyle">bold</item>
<item name="android:textColor">@color/solid_red</item>
<item name="android:duration">200</item>
<item name="android:textColorHighlight">@color/solid_red</item>
<!-- Label color in TRUE state and bar color FALSE and TRUE State -->
<item name="colorAccent">@color/solid_red</item>
<item name="colorControlNormal">@color/solid_red</item>
<item name="colorControlActivated">@color/solid_red</item>
<item name="colorPrimary">@color/solid_red</item>
<item name="colorPrimaryDark">@color/solid_red</item>
<android.support.design.widget.TextInputLayout
android:id="@+id/input_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
app:errorTextAppearance="@style/TextLabelInput"
>
hint text color manage over your main theme
which are colorPrimary and colorAccent
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
Upvotes: 0