我第一次使用新的 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("必填字段")
之后 setError(null)
我做了很多研究,但找不到任何有用的东西,这到底是什么问题??
更新
调查 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));
}
}
调试代码我发现在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 的可绘制文件夹中创建一个文件
<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("error message") 然后运行 setError(null) 时存在
更新 2 这是我用来验证输入的代码
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;
}
我要疯了!!!
最佳答案
我遇到了类似的问题,并找到了一个简单的解决方案。如果我们为 TextInputLayout
内的 EditText
设置自定义背景可绘制对象/颜色,则会出现此问题。对此的解决方案是子类化 TextInputLayout
并覆盖 setError()
和 drawableStateChanged()
方法并将我们的自定义 drawable/color 设置为EditText 的
背景。例如,我为我的 EditText 的
背景设置了一个圆角可绘制对象,下面是我的子类,
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 编码:)
关于android TextInputLayout 在将错误设置为 null 后更改 EditText 样式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34182435/