如何使 TextInputLayout 中的错误消息显示在中心
How to make error message in TextInputLayout appear in center
目前看起来与此布局相关:
<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">
如何将错误信息"password must at least be 8 characters"设置为重心?
我尝试使用 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>
我想知道是否有任何方法可以从框架中处理它..似乎没有。
但 TextInputLayout 的工作方式是:
- 提示 将在用户触摸时 显示在 EditText 之上。
- 错误消息 将仅显示在 TextInputLayout 下 并对齐开始。
由于提示和错误消息之间的错位,我的 EditText 有 40dp left_margin。所以现在,我从 EditText 中删除了 left_margin 40dp 并将其应用于 TextInputLayout 本身,因此现在看起来不错。
经验教训 :-) 如果必须将任何边距应用到 EditText,最好同样应用到 TextInputLayout 以保持正确放置提示和错误消息。
这里有一个解决方案,无论您的 TextInputLayout 有多大,它始终将错误消息居中。
您创建了一个 class,它 从 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);
}
}
}
}
我是通过为错误视图设置开始边距来实现的。下面你可以看到我对 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);
}
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)
}}
@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);
}
}
}
您好,如果您使用最新版本的 material 设计(v 1.2 及更高版本),您必须使用这种方式:(我将重力设置为结束以支持 rtl)
谢谢
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
}
}
用于对齐错误文本的自定义 TextInputLayout class。
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
。
目前看起来与此布局相关:
<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">
如何将错误信息"password must at least be 8 characters"设置为重心?
我尝试使用 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>
我想知道是否有任何方法可以从框架中处理它..似乎没有。
但 TextInputLayout 的工作方式是:
- 提示 将在用户触摸时 显示在 EditText 之上。
- 错误消息 将仅显示在 TextInputLayout 下 并对齐开始。
由于提示和错误消息之间的错位,我的 EditText 有 40dp left_margin。所以现在,我从 EditText 中删除了 left_margin 40dp 并将其应用于 TextInputLayout 本身,因此现在看起来不错。
经验教训 :-) 如果必须将任何边距应用到 EditText,最好同样应用到 TextInputLayout 以保持正确放置提示和错误消息。
这里有一个解决方案,无论您的 TextInputLayout 有多大,它始终将错误消息居中。
您创建了一个 class,它 从 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);
}
}
}
}
我是通过为错误视图设置开始边距来实现的。下面你可以看到我对 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);
}
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)
}}
@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);
}
}
}
您好,如果您使用最新版本的 material 设计(v 1.2 及更高版本),您必须使用这种方式:(我将重力设置为结束以支持 rtl)
谢谢
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
}
}
用于对齐错误文本的自定义 TextInputLayout class。
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
。