新しい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>
_
何IS HAPPENING:
私が走るとき
_setError("error message")
_
editTextの背景とヒントテキストの色全体が赤になり、ここからは問題ありません。問題は私が走るときです
_setError(null)
_
editTextのスタイルは元のスタイルから完全に変更されています。
開始状況:
[〜#〜] after [〜#〜]setError("mandatory field")
[〜#〜] after [〜#〜]setError(null)
たくさん調べてみましたが、何も役に立たなかったのですが、一体何が問題なのでしょうか?
[〜#〜]更新[〜#〜]
Android setError()
メソッドのソースコードを調べてみました
_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)を実行した場合にのみ、問題が発生することに気付きました。
UPDATE 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;
}
_
私はおかしくなりそうだ!!!
私は同様の問題に遭遇し、それに対する簡単な解決策を見つけました。この問題は、カスタムの背景の描画可能/色をEditText
内のTextInputLayout
に設定した場合に発生します。これに対する解決策は、TextInputLayout
をサブクラス化し、setError()
メソッドとdrawableStateChanged()
メソッドをオーバーライドし、カスタムドローアブル/カラーをEditText's
背景として再度設定することです。 。たとえば、EditText's
の背景に丸みを帯びたドローアブルセットがありました。以下は私のサブクラスです、
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コーディング:)
エラーをnullに設定した後、色を希望の色に戻す必要があります。何かのようなもの:
yourEditText.setError(null);
yourEditText.getBackground().mutate().setColorFilter(
ContextCompat.getColor(getContext() , R.color.somecolor),
PorterDuff.Mode.SRC_ATOP);
テキスト入力のスタイルを設定します
<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);
ここで、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の背景ドローアブルがnullであるかどうかを判断し、常にnullを返すため、結果は、editTextの背景がエラーテキストの色によって変更されないことです。
これでsetErrorのみの解決策を得ました link
つまり、カスタムTextInputLayoutを使用しました
これは私のカスタムTextInputLayoutです
<com.adminworksite.Design.NoChangingBackgroundTextInputLayout
Android:id="@+id/city_til_of_job_create"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:layout_below="@+id/tv_placeholder_five"
Android:layout_marginLeft="@dimen/left_right"
Android:layout_marginRight="@dimen/left_right"
app:counterEnabled="true"
app:counterMaxLength="35">
<EditText
Android:id="@+id/city_et_of_job_create"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:background="@drawable/edittext_background"
Android:inputType="text"
Android:paddingLeft="@dimen/left_right"
Android:paddingRight="@dimen/left_right" />
</com.adminworksite.Design.NoChangingBackgroundTextInputLayout>
しかし、長さの制限をTextInputLayoutに設定した場合、つまり.
app:counterEnabled="true"
app:counterMaxLength="35"
制限を超えても色は表示され、ピンクに変わります
だから私はそれのための1つのソリューションを構築し、その編集テキストにaddTextChangedListenerを使用し、コードで背景を設定しました
コードスニペット
editText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (s.length() == 0) {
textInputLayout.setErrorEnabled(true);
textInputLayout.setError("Input should not be empty!");
} else {
textInputLayout.setErrorEnabled(false);
}
}
@Override
public void afterTextChanged(Editable s) {
setBackgroundToEt(editText);
}
});
private void setBackgroundToEt(EditText editText) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
editText.setBackground(getResources().getDrawable(R.drawable.edittext_background));
}
}
最後に検証メソッド内で、editTextにsetbackgroundを再び使用しました
コードスニペット:
private boolean validateInputs() {
//validation code...
setBackgroundToEt(editText);
}