Android TextInputLayout中错误(或提示)文本中的图标

12
我正在使用TextInputLayoutHelper小部件,以符合材料设计指南中浮动标签输入的要求。它目前看起来像这样:floating input label with error message

我的代码

在我的活动的onCreate函数中,我有:
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    val passwordInputLayout = this.findViewById<TextInputLayoutHelper>(R.id.input_layout_password)
    passwordInputLayout.error = "8+ characters and at least one uppercase letter, a number, and a special character (\$, #, !)"
    passwordInputLayout.isErrorEnabled = true
}

我的xml里的小部件看起来像...

<TextInputLayout
    android:id="@+id/input_layout_password"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:theme="@style/EditTextTheme"
    app:errorEnabled="true"
    app:errorTextAppearance="@style/ErrorAppearance"
    app:passwordToggleDrawable="@drawable/asl_password_visibility"
    app:passwordToggleEnabled="true"
    app:passwordToggleTint="?colorControlNormal">

    <EditText
        android:id="@+id/password_edit_text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:ems="10"
        android:hint="@string/set_a_password"
        android:inputType="textPassword"
        android:singleLine="true" />

</TextInputLayout>

我想要做什么

我想在错误/提示文本中(感叹号三角形)右侧放置一个图标。

带有错误图标的输入模拟

我的尝试

尝试1

我发现了一个实现方法,它使用setError(text, drawable),但我正在使用Kotlin,所以setError不可用。

因此,我尝试了:

val warningIcon = ResourcesCompat.getDrawable(resources, R.drawable.ic_warning_black_24dp, null)
warningIcon?.setBounds(0, 0, warningIcon.intrinsicWidth, warningIcon.intrinsicHeight)

passwordInputLayout.error = "8+ characters and at least one uppercase letter, a number, and a special character (\$, #, !) $warningIcon"

但这并不能渲染出可绘制物,只会得到一个资源路径的字符串。

尝试二

我发现另外一个方法是重写TextInputLayoutHelper以便在文本旁边设置一个可绘制物。正如您所看到的,setError仅包含接口override fun setError(error: CharSequence?),其中没有drawable参数。

override fun setError(error: CharSequence?) {
    super.setError(error)

    val warningIcon = ResourcesCompat.getDrawable(resources, R.drawable.ic_warning_black_24dp, null)
    warningIcon?.setBounds(0, 0, warningIcon.intrinsicWidth, warningIcon.intrinsicHeight)
    // mHelperView is a TextView used in my custom `TextInputLayout` override widget
    mHelperView!!.setCompoundDrawables(null, null, warningIcon, null)
}

是否有覆盖或内置的“Android方式”来将此图标添加到错误/提示文本旁边?



把所有的EditText放在FrameLayout里面,再在上面放一个View怎么样? - Uriel Frankel
@UrielFrankel 我对这样的实现唯一的犹豫是,我想坚持使用“本机Android”的方式来处理事情,通过使用 app:errorEnabledapp:errorTextAppearance 来控制我的错误样式/位置。我不想每次想使用图标时都要担心定位我的错误文本。但这绝对是解决我遇到的问题的有效方法,谢谢! - james
3个回答

3
您可以像这样使用带有ImageSpan的SpannableString
val errorDrawable = ContextCompat.getDrawable(context!!, R.drawable.ic_error)
your_text_input_layout.error = SpannableString("your string").apply {
                setSpan(ImageSpan(errorDrawable, ImageSpan.ALIGN_BASELINE), 0, 1, Spanned.SPAN_INCLUSIVE_EXCLUSIVE)

如果根据这个答案 https://dev59.com/Y3A75IYBdhLWcg3wqK7_#3177667 设置可扩展字符串,这个想法是可行的。 - Mia

0

你想把一个图标放在 TextInputLayout 的错误容器内

如果你查看真实的布局

enter image description here

你会发现你的TextView甚至具有wrap content的属性。
同样适用于SDK源代码。
if (enabled) {
    mErrorView = new AppCompatTextView(getContext());
    mErrorView.setId(R.id.textinput_error);
    ...

因此,按原样没有地方在右侧插入图标。

  • 一种可能的解决方案是在布局中编程查找此视图,更改宽度并应用可绘制项。
  • 第二个(也可能是最简单的)解决方案是实现自己的简单错误布局,并且不为TextInputLayout设置错误,而是自己管理错误状态。

0
这可能会帮助到遇到类似问题的其他人。我查看了源代码。问题在于setError(text, drawable)是在EditText类中定义的,而不是你的布局所基于的TextInputLayout
我有类似的代码和问题,因为TextInputLayout没有任何方法来替换Drawable,所以我们必须在TextInputLayout下面创建一个TextView来模拟错误消息。

这个问题的要求是将图标放在错误消息的右侧,您的建议是将图标放在编辑文本的右侧。 - Mia

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接