背景が「通常の」EditTextであるが、TextInputEditTextのエラー処理(「!」ドローアブルは表示されず、下部にエラーメッセージが表示される)を伴うEditTextが必要です。
私はこのようなものを得ました:
<Android.support.design.widget.TextInputLayout
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
app:setError="@{viewModel.error}">
<Android.support.design.widget.TextInputEditText
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:background="@drawable/simple_edit_text_background"
Android:ellipsize="end"
Android:inputType="textMultiLine|textNoSuggestions"
Android:text="@={viewModel.value}"
style="@style/MyEditTextStyle" />
</Android.support.design.widget.TextInputLayout>
しかし、TextInputLayoutにエラーを設定すると、背景のドローアブル(通常のTextInputEditTextでは下線)がエラーTextViewの色に変更されるようです。
そして、これは私のEditTextがどのように見えるかです:
次のメソッド内のTextInputLayoutのコードで確認できます。
private void updateEditTextBackground() {
if (mEditText == null) {
return;
}
Drawable editTextBackground = mEditText.getBackground();
if (editTextBackground == null) {
return;
}
ensureBackgroundDrawableStateWorkaround();
if (Android.support.v7.widget.DrawableUtils.canSafelyMutateDrawable(editTextBackground)) {
editTextBackground = editTextBackground.mutate();
}
if (mErrorShown && mErrorView != null) {
// Set a color filter of the error color
editTextBackground.setColorFilter(
AppCompatDrawableManager.getPorterDuffColorFilter(
mErrorView.getCurrentTextColor(), PorterDuff.Mode.SRC_IN));
} else if (mCounterOverflowed && mCounterView != null) {
// Set a color filter of the counter color
editTextBackground.setColorFilter(
AppCompatDrawableManager.getPorterDuffColorFilter(
mCounterView.getCurrentTextColor(), PorterDuff.Mode.SRC_IN));
} else {
// Else reset the color filter and refresh the drawable state so that the
// normal tint is used
DrawableCompat.clearColorFilter(editTextBackground);
mEditText.refreshDrawableState();
}
}
背景色を更新するコードのブロックはここにあります:
if (mErrorShown && mErrorView != null) {
// Set a color filter of the error color
editTextBackground.setColorFilter(
AppCompatDrawableManager.getPorterDuffColorFilter(
mErrorView.getCurrentTextColor(), PorterDuff.Mode.SRC_IN));
}
このメソッドはプライベートなので、オーバーライドできません。また、エラーTextViewの色を赤にしたいので、これまでのところ解決策はありません。何か案が?
1つの解決策は、setError
が呼び出された直後に背景色をデフォルト値にリセットすることですが、エラーがに設定されると発生するonError
のようなメソッドを持つコールバックです。 TextView/EditText?
私はこのようにTextInputLayoutをオーバーライドすることでこれを自分で解決することができます:
_public class NoChangingBackgroundTextInputLayout extends TextInputLayout {
public NoChangingBackgroundTextInputLayout(Context context) {
super(context);
}
public NoChangingBackgroundTextInputLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public NoChangingBackgroundTextInputLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public void setError(@Nullable CharSequence error) {
ColorFilter defaultColorFilter = getBackgroundDefaultColorFilter();
super.setError(error);
//Reset EditText's background color to default.
updateBackgroundColorFilter(defaultColorFilter);
}
@Override
protected void drawableStateChanged() {
ColorFilter defaultColorFilter = getBackgroundDefaultColorFilter();
super.drawableStateChanged();
//Reset EditText's background color to default.
updateBackgroundColorFilter(defaultColorFilter);
}
private void updateBackgroundColorFilter(ColorFilter colorFilter) {
if(getEditText() != null && getEditText().getBackground() != null)
getEditText().getBackground().setColorFilter(colorFilter);
}
@Nullable
private ColorFilter getBackgroundDefaultColorFilter() {
ColorFilter defaultColorFilter = null;
if(getEditText() != null && getEditText().getBackground() != null)
defaultColorFilter = DrawableCompat.getColorFilter(getEditText().getBackground());
return defaultColorFilter;
}
}
_
見てわかるように、setErrorが呼び出された後、EditTextの背景をデフォルトの色にリセットしますが、メソッドdrawableStateChanged()
でもリセットします。エラーも。
これが最良の解決策であるとは確信していませんが、これ以上の解決策が得られない場合は、当面解決済みとしてマークします。
同じ問題がありました。検索してヒットして実行した後、私はこの問題を解決する簡単な方法を見つけました-
この最も簡単な方法を試してください-
<Android.support.design.widget.TextInputLayout
Android:id="@+id/til_description"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:layout_marginTop="8dp"
app:errorText="@{feedbackViewModel.descError}"
>
<EditText
style="@style/TextInputLayoutEditText"
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
Android:background="@drawable/desc_field_selector"
**Android:paddingTop="10dp"**
**Android:paddingBottom="7dp"**
Android:gravity="top|left"
Android:hint="@string/description"
Android:inputType="textMultiLine"
Android:lines="4"
Android:onTextChanged="@{(text, start, before, count) -> feedbackViewModel.onDescriptionTextChanged(text)}"
Android:scrollHorizontally="false"
Android:scrollbarStyle="insideInset"
Android:scrollbars="vertical"
Android:text="@={feedbackViewModel.description}"/>
</Android.support.design.widget.TextInputLayout>
そしてAndroid:background = "@ drawable/desc_field_selector"-
<selector xmlns:Android="http://schemas.Android.com/apk/res/Android">
<item Android:drawable="@drawable/rectangle_blue_border_background"
Android:state_pressed="true"/>
<item Android:drawable="@drawable/rectangle_blue_border_background"
Android:state_enabled="true"
Android:state_focused="true"
Android:state_window_focused="true"/>
<item Android:drawable="@drawable/rectangle_black_border_background"/>
</selector>
これで、元の形状(@ drawable/rectangle_black_border_background)は次のようになります-
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:Android="http://schemas.Android.com/apk/res/Android">
**<item Android:state_focused="false" Android:top="5dp">**
<shape>
**<solid Android:color="@Android:color/transparent"/>**
<stroke Android:width="1dp" Android:color="@Android:color/secondary_text_light"/>
<corners Android:radius="5dp"/>
</shape>
</item>
</layer-list>
そして、元の形状(@ drawable/rectangle_blue_border_background)は次のようになります-
<layer-list xmlns:Android="http://schemas.Android.com/apk/res/Android">
**<item Android:state_focused="true" Android:top="5dp">**
<shape>
**<solid Android:color="@Android:color/transparent"/>**
<stroke Android:width="@dimen/one_dip" Android:color="@color/colorAccent"/>
<corners Android:radius="5dp"/>
</shape>
</item>
</layer-list>
注-**行は非常に重要です-
**注-**必要に応じて、アイテムと無地のパディング値とトップ値を変更します(無地の線を削除することもできます)。
それだけです:-)ハッピーコーディング+1
受け入れられたソリューションを https://stackoverflow.com/a/40379564/291414 および https://stackoverflow.com/a/44744941/291414 で整理して、私は別のソリューションを書きましたクラス。 EditTextに特別な背景(background_1)がある場合、エラー時にbackground_2に変わります。エラーが消えると、再びbackground_1に戻ります。赤い塗りつぶしは実行されません。
public class YourTextInputLayout extends TextInputLayout {
private Drawable drawable1; // Normal background.
private Drawable drawable2; // Error background.
public YourTextInputLayout(Context context) {
super(context);
}
public YourTextInputLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public YourTextInputLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void drawableStateChanged() {
super.drawableStateChanged();
replaceBackground();
}
@Override
public void setError(@Nullable final CharSequence error) {
super.setError(error);
replaceBackground();
}
public void setDrawable1(Drawable drawable) {
this.drawable1 = drawable;
}
public void setDrawable2(Drawable drawable) {
this.drawable2 = drawable;
}
private void replaceBackground() {
EditText editText = getEditText();
if (editText != null) {
editText.setBackground(isErrorEnabled() ? drawable2 : drawable1);
Drawable drawable = editText.getBackground();
if (drawable != null) {
drawable.clearColorFilter();
}
}
}
}
OnCreate()/ onCreateView()で初期化した後のアクティビティ/フラグメント呼び出し:
YourTextInputLayout inputLayout = ...;
inputLayout.setDrawable1(ContextCompat.getDrawable(getContext(), R.drawable.background_1));
inputLayout.setDrawable2(ContextCompat.getDrawable(getContext(), R.drawable.background_2));
XMLレイアウトで次のように呼び出します。
<com.example.package.YourTextInputLayout
Android:id="@+id/container"
Android:layout_width="match_parent"
Android:layout_height="wrap_content" >
<EditText
...