在将错误设置为null之后,android TextInputLayout更改EditText样式

我第一次使用新的Android小部件TextInputLayout,这是非常好的,但我使用setError方法面临一些问题

这是我的xml

<android.support.design.widget.TextInputLayout android:id="@+id/userData_txtNameWrapper" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" android:textColorHint="@color/light_gray" app:hintTextAppearance="@style/TextAppearence.App.TextInputLayout"> <EditText android:id="@+id/userData_txtName" style="@style/bold_textbox_style" android:layout_width="match_parent" android:layout_height="@dimen/textinut_height" android:layout_margin="5dp" android:hint="name" android:imeOptions="actionNext" android:inputType="text" android:paddingTop="10dp" android:textSize="@dimen/medium_text"/> </android.support.design.widget.TextInputLayout> 

发生什么事:

当我跑步

 setError("error message") 

整个EditText背景和提示文字颜色变成红色,因为这里没问题。 问题是当我跑步

 setError(null) 

EditText的样式完全改变了原来的样子。

开始的情况:

聚焦 聚焦 重点 重点

setError("mandatory field")

在这里输入图像说明

AFER setError(null)

在这里输入图像说明

我做了很多研究,但找不到有用的东西,这个问题到底是怎么回事?

UPDATE

在调查setError()方法的android源代码中,我发现这个

 public void setError(@Nullable CharSequence error) { if (!mErrorEnabled) { if (TextUtils.isEmpty(error)) { // If error isn't enabled, and the error is empty, just return return; } // Else, we'll assume that they want to enable the error functionality setErrorEnabled(true); } if (!TextUtils.isEmpty(error)) { ViewCompat.setAlpha(mErrorView, 0f); mErrorView.setText(error); ViewCompat.animate(mErrorView) .alpha(1f) .setDuration(ANIMATION_DURATION) .setInterpolator(AnimationUtils.FAST_OUT_SLOW_IN_INTERPOLATOR) .setListener(new ViewPropertyAnimatorListenerAdapter() { @Override public void onAnimationStart(View view) { view.setVisibility(VISIBLE); } }) .start(); // Set the EditText's background tint to the error color mErrorShown = true; updateEditTextBackground(); updateLabelVisibility(true); } else { if (mErrorView.getVisibility() == VISIBLE) { ViewCompat.animate(mErrorView) .alpha(0f) .setDuration(ANIMATION_DURATION) .setInterpolator(AnimationUtils.FAST_OUT_SLOW_IN_INTERPOLATOR) .setListener(new ViewPropertyAnimatorListenerAdapter() { @Override public void onAnimationEnd(View view) { view.setVisibility(INVISIBLE); updateLabelVisibility(true); } }).start(); // Restore the 'original' tint, using colorControlNormal and colorControlActivated mErrorShown = false; updateEditTextBackground(); } } private void updateEditTextBackground() { if (mErrorShown && mErrorView != null) { // Set the EditText's background tint to the error color ViewCompat.setBackgroundTintList(mEditText, ColorStateList.valueOf(mErrorView.getCurrentTextColor())); } else if (mCounterOverflowed && mCounterView != null) { ViewCompat.setBackgroundTintList(mEditText, ColorStateList.valueOf(mCounterView.getCurrentTextColor())); } else { final TintManager tintManager = TintManager.get(getContext()); ViewCompat.setBackgroundTintList(mEditText, tintManager.getTintList(R.drawable.abc_edit_text_material)); } } 

并debugging代码,我发现在updateEditTextBackground()执行的代码片段如下

 final TintManager tintManager = TintManager.get(getContext()); ViewCompat.setBackgroundTintList(mEditText, tintManager.getTintList(R.drawable.abc_edit_text_material)); 

这似乎是Android是任意取代EditText的背景色调。 我试着用这个代码在名为abc_edit_text_material.xml的可绘制文件夹中创build一个文件

 <inset xmlns:android="http://schemas.android.com/apk/res/android" android:insetLeft="@dimen/abc_edit_text_inset_horizontal_material" android:insetRight="@dimen/abc_edit_text_inset_horizontal_material" android:insetTop="@dimen/abc_edit_text_inset_top_material" android:insetBottom="@dimen/abc_edit_text_inset_bottom_material"> <selector> <item android:state_enabled="false" android:drawable="@color/white"/> <item android:state_pressed="false" android:state_focused="false" android:drawable="@color/white"/> <item android:drawable="@color/white"/> </selector> </inset> 

但这是setError(null)后的结果

在这里输入图像说明

此外,我注意到,只有当我运行setError(“错误消息”),然后setError(null)

更新2这是我用来validation我的input的代码

 public boolean validateInputs() { mTxtNameWrapper.setError(null); mTxtLastNameWrapper.setError(null); mTxtEmailWrapper.setError(null); mTxtCountryWrapper.setError(null); mTxtIdCardWrapper.setError(null); mTxtFiscalCodeWrapper.setError(null); mLblDocTypeError.setVisibility(View.GONE); if (Strings.isNullOrEmpty(mTxtName.getText().toString())) { mTxtNameWrapper.setError("Mandatory field"); return false; } if (Strings.isNullOrEmpty(mTxtLastName.getText().toString())) { mTxtLastNameWrapper.setError("Mandatory field"); return false; } if (Strings.isNullOrEmpty(mTxtEmail.getText().toString())) { mTxtEmailWrapper.setError("Mandatory field"); return false; } if (!android.util.Patterns.EMAIL_ADDRESS.matcher(mTxtEmail.getText().toString()).matches()) { mTxtEmailWrapper.setError("Invalid email format"); return false; } if (Strings.isNullOrEmpty(mTxtCountry.getText().toString())) { mTxtCountryWrapper.setError("Mandatory field"); return false; } if (mRdgIdType.getCheckedRadioButtonId() == -1) { mLblDocTypeError.setText("Select a document type"); mLblDocTypeError.setVisibility(View.VISIBLE); return false; } if (Strings.isNullOrEmpty(mTxtIdCard.getText().toString())) { mTxtIdCardWrapper.setError("Mandatory field"); return false; } if (Strings.isNullOrEmpty(mTxtFiscalCode.getText().toString())) { mTxtFiscalCodeWrapper.setError("Mandatory field"); return false; } return true; } 

我要疯了!!!

Solutions Collecting From Web of "在将错误设置为null之后,android TextInputLayout更改EditText样式"

我碰到类似的问题,并find一个简单的解决scheme。 如果我们为TextInputLayoutEditText设置自定义背景drawable / color,则会发生此问题。 解决这个问题的方法是setError() TextInputLayout并重写setError()drawableStateChanged()方法,并将我们的自定义drawable / color设置为EditText's背景。 例如,我的EditText's背景有一个圆angular的可绘画集,下面是我的子类,

 public class RoundedBorderedTextInputLayout extends TextInputLayout { private Context context; public RoundedBorderedTextInputLayout(Context context) { super(context); this.context = context; } public RoundedBorderedTextInputLayout(Context context, AttributeSet attrs) { super(context, attrs); this.context = context; } public RoundedBorderedTextInputLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); this.context = context; } @Override protected void drawableStateChanged() { super.drawableStateChanged(); EditText editText = getEditText(); if(editText != null) { editText.setBackground(ContextCompat.getDrawable(this.context, R.drawable.custom_rounded_edittext)); } } @Override public void setError(@Nullable final CharSequence error) { super.setError(error); EditText editText = getEditText(); if(editText != null) { editText.setBackground(ContextCompat.getDrawable(this.context, R.drawable.custom_rounded_edittext)); } } } 

然后在xml中使用您的自定义类,

 <com.example.RoundedBorderedTextInputLayout android:id="@+id/text_input_layout" android:layout_width="match_parent" android:layout_height="wrap_content"> <EditText android:id="@+id/edittext" android:layout_width="match_parent" android:layout_height="wrap_content" android:inputType="textPassword"/> </com.example.RoundedBorderedTextInputLayout> 

希望这可以帮助。 快乐的Android编码:)

将错误设置为空之后,您只需将颜色更改为任何所需的颜色即可。 就像是:

 yourEditText.setError(null); yourEditText.getBackground().mutate().setColorFilter( ContextCompat.getColor(getContext() , R.color.somecolor), PorterDuff.Mode.SRC_ATOP); 

这是一个support:design:23.2.0 bug support:design:23.2.0 (可能还有旧版本),这是报告的问题,并已在23.3.0 更新

设置你的textinput风格

 <style name="TextAppearence.App.TextInputLayout" parent="@android:style/TextAppearance"> <item name="android:textColor">@color/colorPrimaryDark</item> <item name="android:textColorHint">@color/colorPrimaryDark</item> <item name="android:textSize">14sp</item> <item name="colorAccent">@color/colorPrimaryDark</item> <item name="colorControlNormal">@color/colorPrimaryDark</item> <item name="colorControlActivated">@color/colorPrimaryDark</item> </style> 

把下面的代码放在你setError(null)

  txt.setError(null); //for plain white backgorund editText.setBackgroundColor(getResources().getColor(android.R.color.white)); //or if you want any other than editText.setBackgroundResource(R.drawable.border); 

其中边框是我的XML

 <?xml version="1.0" encoding="UTF-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/listview_background_shape"> <stroke android:width="2dp" android:color="#ff207d94" /> <padding android:left="2dp" android:top="2dp" android:right="2dp" android:bottom="2dp" /> <corners android:radius="5dp" /> <solid android:color="#ffffffff" /> </shape> 

我有一个简单的方法来解决这个问题:

1,新增一个类扩展android.support.design.widget.TextInputEditText; 2,覆盖getBackground()方法,使其返回null;

因为TextInputLayout中的updateEditTextBackground()方法将判断editText的背景drawable是否为null,现在总是返回null,结果是editText的背景不会被错误的文字颜色所改变。