I have make an EditText inside TextInputLayout. I am setting a drawableLeft to an EditText at runtime in my code, but as soon as I add the drawableLeft the floating hint inside TextInputLayout shifts to right leaving the space equal to drawable width. But I dont want that space in hint, so help me to resolve this!!
- 1,663
- 3
- 17
- 28
-
please post your xml – Rahul Khurana Sep 16 '16 at 11:38
-
Use _setCompoundDrawablePadding_ – Piyush Sep 16 '16 at 11:46
3 Answers
TextInputLayout uses a library-restricted helper class – CollapsingTextHelper – to manipulate its hint text. The instance of this helper is private, and none of the attributes associated with its layout are exposed, so we'll need to use a little reflection to get access to it. Furthermore, its properties are set and recalculated every time the TextInputLayout is laid out, so it makes sense to subclass TextInputLayout, override its onLayout() method, and make our adjustments there.
import android.content.Context
import android.graphics.Rect
import android.util.AttributeSet
import com.google.android.material.textfield.TextInputLayout
class CustomTextInputLayout @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = com.google.android.material.R.attr.textInputStyle
) : TextInputLayout(context, attrs, defStyleAttr) {
private val collapsingTextHelper = try {
TextInputLayout::class.java.getDeclaredField("collapsingTextHelper")
.apply { isAccessible = true }.get(this)
} catch (e: Exception) {
null
}
private val recalculateMethod = collapsingTextHelper?.let { helper ->
try {
helper.javaClass.getDeclaredMethod("recalculate")
} catch (e: Exception) {
null
}
}
private val collapsedBounds = collapsingTextHelper?.let { helper ->
try {
helper.javaClass.getDeclaredField("collapsedBounds")
.apply { isAccessible = true }.get(helper) as Rect
} catch (e: Exception) {
null
}
}
override fun onLayout(
changed: Boolean,
left: Int,
top: Int,
right: Int,
bottom: Int
) {
super.onLayout(changed, left, top, right, bottom)
val edit = editText ?: return
val helper = collapsingTextHelper ?: return
val recalculate = recalculateMethod ?: return
val bounds = collapsedBounds ?: return
bounds.left = edit.left + edit.paddingLeft
try {
recalculate.invoke(helper)
} catch (e: Exception) {
// fail silently
}
}
}
The custom class is a drop-in replacement for the regular TextInputLayout. For example:
<com.example.app.CustomTextInputLayout
android:id="@+id/text_input_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Model (Example i10, Swift, etc.)"
app:hintTextAppearance="@style/TextLabel">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/edit_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:drawableLeft="@drawable/bmw"
android:text="M Series" />
</com.example.app.CustomTextInputLayout>
- 38,532
- 8
- 99
- 95
-
1add these lines to the proguard rules so that it will still work on your production build: `-keep class android.support.design.widget.TextInputLayout{ *; }` `-keep class android.support.design.widget.CollapsingTextHelper{ *; }` – Tim Oct 03 '18 at 15:08
-
This latest version doesn't seem to require any special ProGuard rules, but I'm not sure why; e.g., maybe something else is already keeping those classes and members, or maybe something changed in the build tools, etc. If anyone runs into any issues, please leave a comment. – Mike M. Mar 18 '23 at 05:07
-
If there are any problems with the reflection or ProGuard or whatever, [this answer](https://stackoverflow.com/a/45511397) shows a slightly different approach that puts the custom class in the library package, therefore giving it direct access to the relevant field and method. You might get a library restriction error, but it can be suppressed. Aside from that, the only downside might be that Material Components' `TextInputLayout` figures the bounds differently 'cause of all its new bells and whistles, so things might not line up correctly with just the basic padding calculations shown there. – Mike M. Mar 18 '23 at 05:51
Yes, Its a common problem that I faced recently.I solved it with simple one line code:
Place a padding between your hint and drawbleleft by using drawble padding.
If you are adding drawble at runtime simply add drawblepadding in xml before hand or you can dynamically add drawble padding.
editText.setCompoundDrawablePadding(your padding value);
Try it and let me know. It worked for me.
- 1,991
- 2
- 16
- 23
