Reputation: 5226
I am using a TextInputLayoutHelper
widget in order to follow the material guidelines for floating label inputs. It currently looks like this:
In my activities onCreate
function, I have:
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
}
and my widget in my xml
looks like...
<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>
I want to put an icon in the error/hint text (the exclamation triangle) to the right of the error text.
I found an implementation which uses setError(text, drawable)
but I am using Kotlin
to setError
is not available.
So I tried:
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"
but that does not render the drawable, only a string of the resource path.
I found another one that overrides the TextInputLayoutHelper
in order to set a drawable next to the text. As you can see, setError
only contains the interface override fun setError(error: CharSequence?)
which does not have a parameter for 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)
}
Is there an override or built in "Android way" to add this icon next to the error/hint text?
Upvotes: 12
Views: 9057
Reputation: 3893
You want to place an icon inside the error container of TextInputLayout
If you check the real layout
You'll find that your textview is even wrap content.
Also in SDK sources
if (enabled) {
mErrorView = new AppCompatTextView(getContext());
mErrorView.setId(R.id.textinput_error);
...
So there is no place to insert an icon on the right AS IS.
TextInputLayout
but manage the error state by yourselfUpvotes: 0
Reputation: 53600
This might help others who've fallen in to similar trouble. I looked at source codes. The thing is setError(text, drawable)
has defined in EditText class not TextInputLayout
as your layout is based on.
I have similar code and issue like you and since TextInputLayout doesn't have any method to replace Drawable then we have to create a TextView below TextInputLayout in order to simulate error message.
Upvotes: 0
Reputation: 121
You can use SpannableString with ImageSpan like this
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)
Upvotes: 3