I was facing the quite same problem but with mutable hints and colored symbol. I'm made this trick with data binding and Spannable
in this way.
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/ti_last_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="4dp"
android:layout_marginEnd="8dp"
app:boxStrokeWidth="0dp"
app:boxStrokeWidthFocused="0dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/et_last_name"
style="@style/EditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:onFocusChangeListener="@{viewModel.onFocusChangeListener(@string/last_name)}"
tools:hint="@string/last_name" />
</com.google.android.material.textfield.TextInputLayout>
viewModel.onFocusChangeListener
defined in this way
fun onFocusChangeListener(hint: String) =
OnFocusChangeListener { view, isFocused ->
(view.parent.parent as TextInputLayout).apply {
val editText = (view as TextInputEditText)
if (isFocused) {
this.hintTextColor = ColorStateList.valueOf(this.getColor(R.color.black))
editText.hint = ""
this.hint = hint
} else {
if (!editText.text.isNullOrBlank()) {
this.defaultHintTextColor = ColorStateList.valueOf(this.getColor(R.color.black))
editText.hint = ""
this.hint = hint
} else {
this.hintTextColor = ColorStateList.valueOf(this.getColor(R.color.hint_color))
val builder = SpannableStringBuilder()
builder.append(hint)
val start = builder.length
val end = start + 1
builder.append("\u2981")
builder.setSpan(
ForegroundColorSpan(Color.RED),
start,
end,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
)
builder.setSpan(
SuperscriptSpan(),
start,
end,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
)
editText.hint = builder
this.hint = ""
}
}
}
}
It's allow to use different hints and colors for focused/not focused states and has colored span.
this.getColor()
it's just extension
fun View.getColor(color: Int): Int {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
this.context.resources.getColor(color, context.theme)
} else {
this.context.resources.getColor(color)
}