How to disable floating while showing error in TextInputLayout

做~自己de王妃 提交于 2019-12-10 13:19:52

问题


<android.support.design.widget.TextInputLayout
        android:id="@+id/productLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:errorEnabled="true">

  <EditText
      android:id="@+id/product"
      android:layout_width="match_parent"
      android:layout_height="@dimen/margin_padding_width_height_6"
      android:cursorVisible="false"
      android:drawableRight="@drawable/ic_arrow_down"
      android:focusableInTouchMode="false"
      android:hint="@string/product"
      android:inputType="none"
      android:paddingEnd="@dimen/margin_padding_width_height_2"
      android:paddingRight="@dimen/margin_padding_width_height_2"
      android:singleLine="true"
      android:textSize="@dimen/text_size_m" />

private boolean validateFields() {
        if (mCategory.getText().toString().isEmpty())
            mCategoryLayout.setError("Please select a category");
        else if (mProducts.getText().toString().isEmpty())
            mProductsLayout.setError("Please select a product");
        else if (mSerialNumber.getText().toString().isEmpty())
            mSerialNumberLayout.setError("Please enter the serial number");
        else
            return true;
        return false;
    }

I have implemented click listener for the EditText,So I don't want float the EditText label to top while setting error on TextInputLayout. How do I disable that ?


回答1:


Starting version 23.2.0 of the Support Library you can call

setHintEnabled(false)

or putting it in your TextInputLayout xml as such :

app:hintEnabled="false"

Though the name might makes you think it removes all hints, it just remove the floating one.

Related docs and issue: http://developer.android.com/reference/android/support/design/widget/TextInputLayout.html#setHintEnabled(boolean)

https://code.google.com/p/android/issues/detail?id=181590




回答2:


If someone wants preserve floating label but don't collapse them when we use setError() on TextInputLayout I found a hacky solution that works with support 25.4.0. Unfortunately it can be corrupted in newer versions.

public class HackedTextInputLayout extends TextInputLayout {

    private int forceExpandedHintBlockFlags = 0;

    @Override
    public void addView(View child, int index, ViewGroup.LayoutParams params) {
        super.addView(child, index, params);

        if (child instanceof EditText) {
            ((EditText) child).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 (!TextUtils.isEmpty(getError()) && TextUtils.isEmpty(s)) {
                        forceExpandedHintBlockFlags++;
                    }
                }

                @Override
                public void afterTextChanged(Editable s) {
                    if (!TextUtils.isEmpty(getError()) && TextUtils.isEmpty(s)) {
                        forceExpandedHintBlockFlags--;
                    }
                }
            });
        }
    }

    @Override
    public void setError(@Nullable CharSequence error) {
        forceExpandedHintBlockFlags++;
        super.setError(error);
        forceExpandedHintBlockFlags--;
    }

    @Nullable
    @Override
    public CharSequence getError() {
        // the main hack is right here
        return forceExpandedHintBlockFlags > 0 ? null : super.getError();
    }

    @Override
    public void setHintTextAppearance(int resId) {
        forceExpandedHintBlockFlags++;
        super.setHintTextAppearance(resId);
        forceExpandedHintBlockFlags--;
    }

    @Override
    protected void drawableStateChanged() {
        forceExpandedHintBlockFlags++;
        super.drawableStateChanged();
        forceExpandedHintBlockFlags--;
    }
}

The main hack is based on source of TextInputLayout. setError(), TextWatcher and few other functions invokes updateLabelState() where we have below condition:

if (hasText || this.isEnabled() && (isFocused || isErrorShowing)) {
    if (force || this.mHintExpanded) {
        this.collapseHint(animate);
    }
} ...

The key here is the value of isErrorShowing = !TextUtils.isEmpty(this.getError()). So if we temporary disable getError() then we always have isErrorShowing == false in that place. Voila :)




回答3:


Try this :

mCategoeyLayout.setHintAnimationEnabled(false);

Later (like on click of Edittext)

mCategoeyLayout.setHintAnimationEnabled(true);



回答4:


  private boolean validateFields() {
    if (mCategory.getText().toString().isEmpty())
        mCategoryLayout.setError("Please select a category");
    else if (mProducts.getText().toString().isEmpty())
        mProductsLayout.setError("Please select a product");
    else if (mSerialNumber.getText().toString().isEmpty())
        mSerialNumberLayout.setError("Please enter the serial number");
    else
        return true;
    return false;
}


来源:https://stackoverflow.com/questions/36083769/how-to-disable-floating-while-showing-error-in-textinputlayout

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!