【问题标题】:How to make error message in TextInputLayout appear in center如何使 TextInputLayout 中的错误消息显示在中心
【发布时间】:2015-11-30 12:16:49
【问题描述】:

目前它看起来与此布局的附件一样:

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

如何将错误信息“密码必须至少为 8 个字符”设置为重心?
我尝试使用 android:gravity="center" 但这没有用。

编辑
包含 EditText 的布局:

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

        <EditText
            android:id="@+id/editTextCurrentPassword"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom"
            android:layout_marginLeft="50dp"
            android:layout_marginRight="50dp"
            android:gravity="center"
            android:hint="@string/current_password"
            android:inputType="textPassword"
            android:textAppearance="?android:attr/textAppearanceMedium"
            android:textColor="@color/black" />
    </android.support.design.widget.TextInputLayout>

【问题讨论】:

标签: android android-textinputlayout android-gravity


【解决方案1】:

我想知道是否有任何方法可以从框架中处理它。似乎没有。

但 TextInputLayout 的工作方式是:
- 提示将在用户触摸时显示在EditText的顶部
- 错误消息将显示在TextInputLayout下方并对齐开始。

由于提示和错误消息之间的错位,我的 EditText 有 40dp 的 left_margin。所以现在,我从 EditText 中删除了 left_margin 40dp 并将其应用于 TextInputLayout 本身,所以它现在看起来很好。

经验教训 :-) 是否必须将任何边距应用于 EditText,如果可能的话,最好将相同的边距应用于 TextInputLayout 以保持正确放置提示和错误消息。

【讨论】:

    【解决方案2】:
    class CenterErrorTextInputLayout(context: Context, attrs: AttributeSet) : TextInputLayout(context, attrs) {
    override fun setErrorTextAppearance(resId: Int) {
        super.setErrorTextAppearance(resId)
        val errorTextView = this.findViewById<TextView>(R.id.textinput_error)
        val errorFrameLayout = errorTextView.parent as FrameLayout
    
        errorTextView.gravity = Gravity.CENTER
        errorFrameLayout.layoutParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)
    }}
    

    【讨论】:

    • 复制粘贴 FTW?
    • 对于那些没有与 OP 相同的问题,但实际上需要以正常边距居中错误消息的人来说,这实际上工作得很好
    【解决方案3】:

    无论您的 TextInputLayout 有多大,这里总是将错误消息居中的解决方案。

    您创建了一个从 TextInputLayout继承的自己的类。然后重写 ShowError(string text, Drawable icon) 方法。如果调用错误,则将 textView 与错误居中。

        public class TextInputLayout_Center : TextInputLayout
        {
            public override void ShowError(string text, Android.Graphics.Drawables.Drawable icon)
            {
                base.ShowError(text, icon);
    
                centerErrorMessage(this);
            }
    
            void centerErrorMessage(ViewGroup view)
            {
                for (int i = 0; i < view.ChildCount; i++)
                {
                    View v = view.GetChildAt(i);
                    if (v.GetType() == typeof(TextView))
                    {
                        v.LayoutParameters = new LayoutParams(ViewGroup.LayoutParams.MatchParent, v.LayoutParameters.Height);
                        ((TextView)v).Gravity = GravityFlags.CenterHorizontal;
                        ((TextView)v).TextAlignment = TextAlignment.Center;
                    }
                    if (v is ViewGroup)
                    {
                        centerErrorMessage((ViewGroup)v);
                    }
                }
            }
        }
    

    【讨论】:

    • 是的,这段代码是用 C# 为 Xamarin 编写的,但基本相同。 @CharlesMadere
    【解决方案4】:

    我通过设置错误视图的起始边距来实现它。下面你可以看到我重写的TextInputLayout 组件的setError 方法。

    @Override
    public void setError(@Nullable CharSequence errorText) {
        // allow android component to create error view
        if (errorText == null) {
            return;
        }
        super.setError(errorText);
        // find this error view and calculate start margin to make it look like centered
        final TextView errorTextInput = (TextView) findViewById(R.id.textinput_error);
        errorTextInput.measure(0, 0);
        int errorWidth = errorTextInput.getMeasuredWidth();
        int layoutWidth = getWidth();
        LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) errorTextInput.getLayoutParams();
        params.setMarginStart((layoutWidth - errorWidth) / 2);
        errorTextInput.setLayoutParams(params);
    }
    

    【讨论】:

      【解决方案5】:
      @Override
      public void setErrorEnabled(boolean enabled) {
          super.setErrorEnabled(enabled);
          if (!enabled)
              return;
          try {
              setErrorGravity(this);
          } catch (Exception e) {
              e.printStackTrace();
          }
      }
      
      private void setErrorGravity(ViewGroup view) throws Exception {
          for (int i = 0; i < view.getChildCount(); i++) {
              View errorView = view.getChildAt(i);
              if (errorView instanceof TextView) {
                  if (errorView.getId() == com.google.android.material.R.id.textinput_error) {
                      FrameLayout errorViewParent = (FrameLayout) errorView.getParent();
                      errorViewParent.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
                      ((TextView) errorView).setGravity(Gravity.RIGHT);
                      ((TextView) errorView).setTypeface(FontUtils.getTypeFace(view.getContext(), FontUtils.FONT_NAZANIN_TAR));
                  }
              }
              if (errorView instanceof ViewGroup) {
                  setErrorGravity((ViewGroup) errorView);
              }
          }
      }
      

      【讨论】:

        【解决方案6】:

        您好,如果您使用最新版本的材料设计(v 1.2 及更高版本),您必须使用这种方式:(我将重力设置为结束以支持 rtl) 谢谢@Emmanuel Guerra

        class MyTextInputLayout : TextInputLayout {
        
            constructor(context: Context) : super(context)
        
            constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
        
            constructor(context: Context, attrs: AttributeSet?, defStyleAttrs: Int) : super(context, attrs, defStyleAttrs)
        
            override fun setErrorEnabled(enabled: Boolean) {
                super.setErrorEnabled(enabled)
                if (!enabled) {
                    return
                }
                try {
                    changeTextAlignment(com.google.android.material.R.id.textinput_error, View.TEXT_ALIGNMENT_VIEW_END)
                    val errorView: ViewGroup = this.getChildAt(1) as LinearLayout
        
                    val params: LinearLayout.LayoutParams = errorView.layoutParams as LinearLayout.LayoutParams
        
                    params.gravity = Gravity.END
        
                    errorView.layoutParams = params
                    //errorView.setPadding(0, 0, 0, 0) //use this to remove error text padding
                    //setErrorIconDrawable(0)
                } catch (e: Exception) {
                    e.printStackTrace()
                }
            }
        
        
            private fun changeTextAlignment(textViewId: Int, alignment: Int) {
                val textView = findViewById<TextView>(textViewId)
                textView.textAlignment = alignment
            }
        }
        

        【讨论】:

          【解决方案7】:

          用于对齐错误文本的自定义 TextInputLayout 类。

          class CenterErrorTextInputLayout @JvmOverloads constructor(
          context: Context,
          attrs: AttributeSet? = null,
          defStyleAttr: Int = 0
          
          ) : TextInputLayout(context, attrs, defStyleAttr) {
          
              override fun setErrorEnabled(enabled: Boolean) {
                  super.setErrorEnabled(enabled)
          
                  if (!enabled) return
          
                  try {
                      setErrorTextAlignment()
                  } catch (e: Exception) {
                      Timber.e(e, "Failed to set error text :    RightErrorTextInputLayout")
                  }
              }
          
              private fun setErrorTextAlignment() {
                  val errorView: TextView = this.findViewById(R.id.textinput_error)
                  errorView.textAlignment = View.TEXT_ALIGNMENT_CENTER
              }
          }
          

          要将文本与末尾对齐,请改用View.TEXT_ALIGNMENT_VIEW_END

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2016-09-10
            • 2017-01-02
            • 2013-02-05
            • 2011-06-28
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多