【问题标题】:TextInputLayout.setError() leaves empty space after clearing the errorTextInputLayout.setError() 清除错误后留下空白空间
【发布时间】:2020-07-01 04:33:57
【问题描述】:

我最近使用了TextInputLayout,它是setError() 方法。我遇到的问题是,当我通过调用 setError(null) 清除错误时,它会在底部留下很多空白空间。

正常:

有错误:

清除错误后:

查看源代码后,我发现他们正在制作视图INVISIBLE而不是GONE

.setListener(new ViewPropertyAnimatorListenerAdapter() {
@Override
public void onAnimationEnd(View view) {
    view.setVisibility(INVISIBLE); // here it is

    updateLabelVisibility(true);
} }).start();

我想知道为什么会这样?如何解决这个问题以避免空白?

【问题讨论】:

  • 其实你是在给它自己的动画吗?

标签: android android-textinputlayout


【解决方案1】:

查看文档

public void setErrorEnabled (boolean enabled)

它说

此布局中是否启用了错误功能。 在通过以下方式设置错误消息之前启用此功能 setError(CharSequence),表示这个布局不会改变 显示错误时的大小。

基于此,尝试在setError() 之前设置setErrorEnabled(true),并在setError(null) 之后设置setErrorEnabled(false)

【讨论】:

  • 你是对的。感谢您指出了这一点。但它仍然占用大量空间,并且在预览布局时也无法预测。我仍然不明白他们为什么这样做。
  • 不太清楚他们为什么要这样实现,是的,拥有 View.GONE 会更好地节省空间,但如果某些复杂的视图组位于 TextInputLayout 之下,它们可能会产生问题,并且它们必须转移下来。
  • 在 seterror 上扩展。但是将 error 设置为 null 或 settingErrorEnabled 设置为 false 不会折叠回布局。
  • setError 在内部调用 setErrorEnabled(true)
  • 太棒了!我为此创建了两个扩展函数: fun TextInputLayout.showError(errorText: String) { this.isErrorEnabled = true this.error = errorText } fun TextInputLayout.removeError() { this.isErrorEnabled = false this.error = null }
【解决方案2】:

方法setErrorEnabled(false)会清除多余的空间,所以在setError(null)之后调用它。

【讨论】:

  • 这个响应给了我预期的结果。谢谢。
  • 谢谢。正是我需要的!
  • 我们为什么需要setError(null)
【解决方案3】:

不要使用setErrorEnabled(boolean),它只是不显示第二次的错误。

public class MyTextInputLayout extends android.support.design.widget.TextInputLayout {

public MyTextInputLayout(Context context) {
    super(context);
}

public MyTextInputLayout(Context context, AttributeSet attrs) {
    super(context, attrs);
}

public MyTextInputLayout(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
}

@Override
public void setError(@Nullable CharSequence error) {
    super.setError(error);

    View layout = getChildAt(1);
    if (layout != null) {
        if (error != null && !"".equals(error.toString().trim())) {
            layout.setVisibility(VISIBLE);
        } else {
            layout.setVisibility(GONE);
        }
    }
}
}

那么只需setError(errorMessage);setError(null);

【讨论】:

  • 工作正常,但它会立即删除文本。有没有办法让它动起来?
【解决方案4】:

参见this 页面。 Google 将在未来的支持库版本中发布此修复程序。它说,

如果您现在想修复它,您可以扩展 TextInputLayout 和 覆盖setErrorEnabled() 方法,但我不能保证 向后兼容性。因为改变状态有一些危险 TextInputLayout.

public class TextInputLayout extends android.support.design.widget.TextInputLayout{


    public TextInputLayout(Context context) {
        super(context);
    }

    public TextInputLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public TextInputLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public void setErrorEnabled(boolean enabled) {
        super.setErrorEnabled(enabled);
        if (enabled) {
            return;
        }
        if (getChildCount() > 1) {
            View view = getChildAt(1);
            if (view != null) {
                view.setVisibility(View.GONE);
            }
        }
    }
}

【讨论】:

  • @HRaval 该错误已在支持库 v23.2.0 中修复,但我尚未验证
  • @ShaodeLu,我检查了23.3.0,他们没有修复它
【解决方案5】:

TextInputLayout 源码如下: 如果您需要清除错误,只需使用

til.setErrorEnabled(false);

这将隐藏错误文本并将底部空间拉伸到其标准大小。

如果您需要再次设置错误,只需使用

til.setError("Your text");

它会自动调用til.setErrorEnabled(true),因为它假定您需要错误功能。

【讨论】:

    【解决方案6】:

    我创建了一个自定义视图以避免重复代码并覆盖 setError 方法。

        public class UserInputView extends TextInputLayout {
    
            public UserInputView(Context context) {
               this(context, null);
            }
    
            public UserInputView(Context context, AttributeSet attrs) {
                this(context, attrs, 0);
            }
    
            public UserInputView(Context context, AttributeSet attrs, int defStyleAttr) {
                super(context, attrs, defStyleAttr);
            }
    
            @Override
            public void setError(@Nullable CharSequence error) {
                boolean isErrorEnabled = error != null;
                setErrorEnabled(isErrorEnabled);
                super.setError(error);
            }
    
         }
    

    【讨论】:

      【解决方案7】:

      这是 kotlin 解决问题的扩展:

      fun TextInputLayout.clearError() {
          error = null
          isErrorEnabled = false
      }
      

      【讨论】:

        【解决方案8】:

        以下代码运行良好

            textInputLatout.getEditText().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() < 1) {
                       textInputLayout.setErrorEnabled(true);
                        textInputLayout.setError("Please enter a value");
                    }
        
                    if (s.length() > 0) {
                        textInputLayout.setError(null);
                        textInputLayout.setErrorEnabled(false);
                    }
        
                }
        
                @Override
                public void afterTextChanged(Editable s) {
        
                }
            });
        

        【讨论】:

          【解决方案9】:

          通过使用mTextInputLayout.setErrorEnabled(false); 我已经解决了这个问题

          【讨论】:

            【解决方案10】:

            那么你应该像这样覆盖它:

            @Override
            public void onAnimationEnd(View view)
            {
                view.setVisibility(GONE); // <-- this is where you make it GONE
            
                updateLabelVisibility(true); 
            }
            

            或者试试这个,例如在一个按钮或任何你使用的东西上:

            final Button btn = (Button) findViewById(R.id.btn);
            btn.setVisibility(View.GONE); //<--- makes the button gone
            

            【讨论】:

            • 抱歉,我没听懂你在说什么。
            • 例如,视图可以是按钮之类的任何东西。
            猜你喜欢
            • 1970-01-01
            • 2015-12-20
            • 2023-03-03
            • 2016-04-22
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多