我在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以编程方式将Error转移到右侧。即使这对我也不起作用。
我不确定还有什么可以尝试的。请建议。
答案 0 :(得分:12)
感谢Mike's answer我能够找到解决方案。
我创建了一个自定义类:
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。我希望我能为你的答案多点赞扬。
答案 1 :(得分:3)
我的自定义课程在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 = LinearLayout.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()
}
}
}
答案 2 :(得分:2)
这是Kotlin中的一种不依赖于视图层次结构的黑客:
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
}
}
}
答案 3 :(得分:1)
对于材料成分版本1.2.0-rc01
,您可以创建一个CustomTextInputLayout,它继承自TextInputLayout,以将文本对齐方式更改为末尾(或您希望的位置),如下所示:
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
类中将对齐方式指定为始终为View.TEXT_ALIGNMENT_VIEW_START
。此类由TextInputLayout使用。
来自IndicatorViewController
类
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...
答案 4 :(得分:0)
如果选择的答案不起作用。下面是另一种解决方案:
创建如下的自定义类:
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);
恭喜!您已完成所需的工作。
答案 5 :(得分:0)
基于 @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
}
}