web-dev-qa-db-ja.com

android TextInputLayoutは、エラーをnullに設定した後、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>
_

何IS HAPPENING:

私が走るとき

_setError("error message") 
_

editTextの背景とヒントテキストの色全体が赤になり、ここからは問題ありません。問題は私が走るときです

_setError(null) 
_

editTextのスタイルは元のスタイルから完全に変更されています。

開始状況:

焦点が合っていない unfocused 集中 focused

[〜#〜] after [〜#〜]setError("mandatory field")

enter image description here

[〜#〜] after [〜#〜]setError(null)

enter image description here

たくさん調べてみましたが、何も役に立たなかったのですが、一体何が問題なのでしょうか?

[〜#〜]更新[〜#〜]

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)の後の結果です

enter image description here

さらに、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;
}
_

私はおかしくなりそうだ!!!

12
Apperside

私は同様の問題に遭遇し、それに対する簡単な解決策を見つけました。この問題は、カスタムの背景の描画可能/色を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コーディング:)

6
Pratima

エラーをnullに設定した後、色を希望の色に戻す必要があります。何かのようなもの:

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

これはsupport:design:23.2.0(および場合によっては古いバージョン)のバグであり、問​​題として報告されました ここ そして23.3.0更新 で修正されました

4
kingdonnaz

テキスト入力のスタイルを設定します

<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>
0
H Raval

この問題を簡単に解決するための秘訣があります。

1、新しいクラスはAndroid.support.design.widget.TextInputEditTextを拡張します; 2、getBackground()メソッドを上書きし、nullを返すようにします。

textInputLayoutのメソッドupdateEditTextBackground()は、editTextの背景ドローアブルがnullであるかどうかを判断し、常にnullを返すため、結果は、editTextの背景がエラーテキストの色によって変更されないことです。

0
peng gao

これで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);
}
0
LEGEND MORTAL