TextInputLayout 错误右对齐
TextInputLayout Error right align
我有一个包含在 TextInputLayout 中的 EditText。我希望在 EditText 下显示错误,但对齐到屏幕的右端。
这是我目前拥有的:
错误显示如下:
我希望它看起来像什么:
我的XML是这样的:
<android.support.design.widget.TextInputLayout
android:id="@+id/text_input_email"
style="@style/forgot_pass_text_inputlayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/tv_enter_email_message"
android:layout_marginTop="@dimen/email_padding_top"
android:hintTextAppearance="@{forgotPasswordVM.hintTextAppearance}"
android:theme="@style/forgot_pass_til_state"
app:error="@{forgotPasswordVM.email.textInputError}">
<EditText
android:id="@+id/actv_email"
style="@style/forgot_pass_edit_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/email_address"
android:imeActionId="@+id/btn_submit"
android:imeOptions="actionSend"
android:inputType="textEmailAddress"
android:maxLines="1"
android:onEditorAction="@{forgotPasswordVM.onEditorAction}"
android:singleLine="true"
app:binding="@{forgotPasswordVM.email.text}" />
</android.support.design.widget.TextInputLayout>
我正在使用数据绑定。
我已经尝试在 EditText 和 TextInputLayout 上设置 android:gravity="right"
和 android:layout_gravity="right"
。两者都不像我想要的那样工作。
我试过在主题和样式中设置正确的引力。两者都对错误没有任何影响。
我已经在 app:errorTextAppearance="@style/right_error"
中应用的样式上尝试了正确的引力。即使这样也行不通。
我尝试通过在 this link 之后使用带有 AlignmentSpan 的 SpannableStringBuilder 以编程方式将错误向右移动。即使那样对我也不起作用。
我不确定还能尝试什么。请提出建议。
感谢 Mike's answer 我找到了解决方案。
我创建了一个自定义 class:
public class CustomTextInputLayout extends TextInputLayout {
public CustomTextInputLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public void setErrorEnabled(boolean enabled) {
super.setErrorEnabled(enabled);
if (!enabled) {
return;
}
try {
Field errorViewField = TextInputLayout.class.getDeclaredField("mErrorView");
errorViewField.setAccessible(true);
TextView errorView = (TextView) errorViewField.get(this);
if (errorView != null) {
errorView.setGravity(Gravity.RIGHT);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
params.gravity = Gravity.END;
errorView.setLayoutParams(params);
}
}
catch (Exception e) {
// At least log what went wrong
e.printStackTrace();
}
}
}
现在我只是用 CustomTextInputLayout 替换了我的 TextInputLayout。
奇迹般有效。非常感谢Mike。我希望我能把这个答案更多地归功于你。
我的习惯 class 使用 Kotlin
class CustomTextInputLayout(context: Context, attrs: AttributeSet) :
TextInputLayout(context, attrs) {
override fun setErrorEnabled(enabled: Boolean) {
super.setErrorEnabled(enabled)
if (!enabled) {
return
}
try {
val layout = this
val errorView : TextView = ((this.getChildAt(1) as ViewGroup).getChildAt(0) as ViewGroup).getChildAt(0) as TextView
(layout.getChildAt(1) as ViewGroup).layoutParams.width = LayoutParams.MATCH_PARENT
(layout.getChildAt(1) as ViewGroup).getChildAt(0).layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT
errorView.gravity = Gravity.END
} catch (e: Exception) {
e.printStackTrace()
}
}
}
如果选择的答案无效。另一种解决方案如下:
创建自定义 class 如下:
public class CustomTextInputLayout extends TextInputLayout
{
public CustomTextInputLayout(Context context, AttributeSet attrs)
{
super(context, attrs);
}
@Override
public void setErrorEnabled(boolean enabled)
{
super.setErrorEnabled(enabled);
if (!enabled)
{
return;
}
try
{
TextView errorView = this.findViewById(R.id.textinput_error);
FrameLayout errorViewParent = (FrameLayout) errorView.getParent();
errorViewParent.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.WRAP_CONTENT));
errorView.setGravity(Gravity.CENTER); // replace CENTER with END or RIGHT
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
然后将您的自定义 TextInputLayout 创建为:
<CustomTextInputLayout
android:id="@+id/til_first_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/activity_horizontal_margin"
app:layout_constraintBottom_toTopOf="@+id/til_last_name">
<EditText
android:id="@+id/et_first_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/first_name"
android:gravity="right"
/>
</CustomTextInputLayout>
之后在您的代码中初始化为:
private CustomTextInputLayout tilFirstName;
tilFirstName = view.findViewById(R.id.til_first_name);
恭喜!你已经完成了你所要求的。
这是 Kotlin 中不依赖于视图层次结构的 hack:
class CustomTextInputLayout @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : TextInputLayout(context, attrs, defStyleAttr) {
override fun setError(errorText: CharSequence?) {
super.setError(errorText)
with(findViewById<TextView>(R.id.textinput_error)) {
// this will work as long as errorView's layout width is
// MATCH_PARENT -- it is, at least now in material:1.2.0-alpha06
textAlignment = TextView.TEXT_ALIGNMENT_VIEW_END
}
}
}
使用 material-componets 版本 1.2.0-rc01
,您可以创建一个继承自 TextInputLayout 的 CustomTextInputLayout,以将 文本对齐方式 更改为末尾(或您想要的位置它是)像这样:
class CustomTextInputLayout : 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
)
} catch (e: Exception) {
e.printStackTrace()
}
}
private fun changeTextAlignment(textViewId: Int, alignment: Int) {
val textView = findViewById<TextView>(textViewId)
textView.textAlignment = alignment
}
}
IndicatorViewController
class 中指定的对齐始终为 View.TEXT_ALIGNMENT_VIEW_START
。此 class 由 TextInputLayout 使用。
来自IndicatorViewController
class
void setErrorEnabled(boolean enabled) {
if (errorEnabled == enabled) {
return;
}
cancelCaptionAnimator();
if (enabled) {
errorView = new AppCompatTextView(context);
errorView.setId(R.id.textinput_error);
if (VERSION.SDK_INT >= 17) {
errorView.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_START);
}
//More code...
基于@Emmanuel Guerra的回答。我也在 helperText 上应用了它:
class CustomTextInputLayout @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = com.google.android.material.R.attr.textInputStyle
) : TextInputLayout(context, attrs, defStyleAttr) {
override fun setErrorEnabled(enabled: Boolean) {
super.setErrorEnabled(enabled)
if (!enabled) return
centerMiniText(com.google.android.material.R.id.textinput_error)
}
override fun setHelperTextEnabled(enabled: Boolean) {
super.setHelperTextEnabled(enabled)
if (!enabled) return
centerMiniText(com.google.android.material.R.id.textinput_helper_text)
}
private fun centerMiniText(textViewId: Int) {
try {
changeTextAlignment(textViewId, View.TEXT_ALIGNMENT_CENTER)
} catch (e: Exception) {
e.printStackTrace()
}
}
@Suppress("SameParameterValue")
private fun changeTextAlignment(textViewId: Int, alignment: Int) {
findViewById<TextView>(textViewId)?.textAlignment = alignment
}
}
我有一个包含在 TextInputLayout 中的 EditText。我希望在 EditText 下显示错误,但对齐到屏幕的右端。
这是我目前拥有的:
错误显示如下:
我希望它看起来像什么:
我的XML是这样的:
<android.support.design.widget.TextInputLayout
android:id="@+id/text_input_email"
style="@style/forgot_pass_text_inputlayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/tv_enter_email_message"
android:layout_marginTop="@dimen/email_padding_top"
android:hintTextAppearance="@{forgotPasswordVM.hintTextAppearance}"
android:theme="@style/forgot_pass_til_state"
app:error="@{forgotPasswordVM.email.textInputError}">
<EditText
android:id="@+id/actv_email"
style="@style/forgot_pass_edit_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/email_address"
android:imeActionId="@+id/btn_submit"
android:imeOptions="actionSend"
android:inputType="textEmailAddress"
android:maxLines="1"
android:onEditorAction="@{forgotPasswordVM.onEditorAction}"
android:singleLine="true"
app:binding="@{forgotPasswordVM.email.text}" />
</android.support.design.widget.TextInputLayout>
我正在使用数据绑定。
我已经尝试在 EditText 和 TextInputLayout 上设置 android:gravity="right"
和 android:layout_gravity="right"
。两者都不像我想要的那样工作。
我试过在主题和样式中设置正确的引力。两者都对错误没有任何影响。
我已经在 app:errorTextAppearance="@style/right_error"
中应用的样式上尝试了正确的引力。即使这样也行不通。
我尝试通过在 this link 之后使用带有 AlignmentSpan 的 SpannableStringBuilder 以编程方式将错误向右移动。即使那样对我也不起作用。
我不确定还能尝试什么。请提出建议。
感谢 Mike's answer 我找到了解决方案。
我创建了一个自定义 class:
public class CustomTextInputLayout extends TextInputLayout {
public CustomTextInputLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public void setErrorEnabled(boolean enabled) {
super.setErrorEnabled(enabled);
if (!enabled) {
return;
}
try {
Field errorViewField = TextInputLayout.class.getDeclaredField("mErrorView");
errorViewField.setAccessible(true);
TextView errorView = (TextView) errorViewField.get(this);
if (errorView != null) {
errorView.setGravity(Gravity.RIGHT);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
params.gravity = Gravity.END;
errorView.setLayoutParams(params);
}
}
catch (Exception e) {
// At least log what went wrong
e.printStackTrace();
}
}
}
现在我只是用 CustomTextInputLayout 替换了我的 TextInputLayout。 奇迹般有效。非常感谢Mike。我希望我能把这个答案更多地归功于你。
我的习惯 class 使用 Kotlin
class CustomTextInputLayout(context: Context, attrs: AttributeSet) :
TextInputLayout(context, attrs) {
override fun setErrorEnabled(enabled: Boolean) {
super.setErrorEnabled(enabled)
if (!enabled) {
return
}
try {
val layout = this
val errorView : TextView = ((this.getChildAt(1) as ViewGroup).getChildAt(0) as ViewGroup).getChildAt(0) as TextView
(layout.getChildAt(1) as ViewGroup).layoutParams.width = LayoutParams.MATCH_PARENT
(layout.getChildAt(1) as ViewGroup).getChildAt(0).layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT
errorView.gravity = Gravity.END
} catch (e: Exception) {
e.printStackTrace()
}
}
}
如果选择的答案无效。另一种解决方案如下:
创建自定义 class 如下:
public class CustomTextInputLayout extends TextInputLayout
{
public CustomTextInputLayout(Context context, AttributeSet attrs)
{
super(context, attrs);
}
@Override
public void setErrorEnabled(boolean enabled)
{
super.setErrorEnabled(enabled);
if (!enabled)
{
return;
}
try
{
TextView errorView = this.findViewById(R.id.textinput_error);
FrameLayout errorViewParent = (FrameLayout) errorView.getParent();
errorViewParent.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.WRAP_CONTENT));
errorView.setGravity(Gravity.CENTER); // replace CENTER with END or RIGHT
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
然后将您的自定义 TextInputLayout 创建为:
<CustomTextInputLayout
android:id="@+id/til_first_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/activity_horizontal_margin"
app:layout_constraintBottom_toTopOf="@+id/til_last_name">
<EditText
android:id="@+id/et_first_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/first_name"
android:gravity="right"
/>
</CustomTextInputLayout>
之后在您的代码中初始化为:
private CustomTextInputLayout tilFirstName;
tilFirstName = view.findViewById(R.id.til_first_name);
恭喜!你已经完成了你所要求的。
这是 Kotlin 中不依赖于视图层次结构的 hack:
class CustomTextInputLayout @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : TextInputLayout(context, attrs, defStyleAttr) {
override fun setError(errorText: CharSequence?) {
super.setError(errorText)
with(findViewById<TextView>(R.id.textinput_error)) {
// this will work as long as errorView's layout width is
// MATCH_PARENT -- it is, at least now in material:1.2.0-alpha06
textAlignment = TextView.TEXT_ALIGNMENT_VIEW_END
}
}
}
使用 material-componets 版本 1.2.0-rc01
,您可以创建一个继承自 TextInputLayout 的 CustomTextInputLayout,以将 文本对齐方式 更改为末尾(或您想要的位置它是)像这样:
class CustomTextInputLayout : 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
)
} catch (e: Exception) {
e.printStackTrace()
}
}
private fun changeTextAlignment(textViewId: Int, alignment: Int) {
val textView = findViewById<TextView>(textViewId)
textView.textAlignment = alignment
}
}
IndicatorViewController
class 中指定的对齐始终为 View.TEXT_ALIGNMENT_VIEW_START
。此 class 由 TextInputLayout 使用。
来自IndicatorViewController
class
void setErrorEnabled(boolean enabled) {
if (errorEnabled == enabled) {
return;
}
cancelCaptionAnimator();
if (enabled) {
errorView = new AppCompatTextView(context);
errorView.setId(R.id.textinput_error);
if (VERSION.SDK_INT >= 17) {
errorView.setTextAlignment(View.TEXT_ALIGNMENT_VIEW_START);
}
//More code...
基于@Emmanuel Guerra的回答。我也在 helperText 上应用了它:
class CustomTextInputLayout @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = com.google.android.material.R.attr.textInputStyle
) : TextInputLayout(context, attrs, defStyleAttr) {
override fun setErrorEnabled(enabled: Boolean) {
super.setErrorEnabled(enabled)
if (!enabled) return
centerMiniText(com.google.android.material.R.id.textinput_error)
}
override fun setHelperTextEnabled(enabled: Boolean) {
super.setHelperTextEnabled(enabled)
if (!enabled) return
centerMiniText(com.google.android.material.R.id.textinput_helper_text)
}
private fun centerMiniText(textViewId: Int) {
try {
changeTextAlignment(textViewId, View.TEXT_ALIGNMENT_CENTER)
} catch (e: Exception) {
e.printStackTrace()
}
}
@Suppress("SameParameterValue")
private fun changeTextAlignment(textViewId: Int, alignment: Int) {
findViewById<TextView>(textViewId)?.textAlignment = alignment
}
}