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!!
The primary use of a TextInputLayout is to act as a wrapper for EditText(or its descendant) and enable floating hint animations. Rule of Thumb : TextInputLayout should wrap TextInputEditText instead of the normal EditText.
You can just set the start and end padding on the inner EditText to 0dp. Here's a screenshot with Show Layout Bounds turned on so you can see that the hints go all the way to the edge of the view.
TextInputLayout
uses a 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.support.design.widget.TextInputLayout;
import android.util.AttributeSet;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class CustomTextInputLayout extends TextInputLayout {
private Object collapsingTextHelper;
private Rect bounds;
private Method recalculateMethod;
public CustomTextInputLayout(Context context) {
this(context, null);
}
public CustomTextInputLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CustomTextInputLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
adjustBounds();
}
private void init() {
try {
Field cthField = TextInputLayout.class.getDeclaredField("mCollapsingTextHelper");
cthField.setAccessible(true);
collapsingTextHelper = cthField.get(this);
Field boundsField = collapsingTextHelper.getClass().getDeclaredField("mCollapsedBounds");
boundsField.setAccessible(true);
bounds = (Rect) boundsField.get(collapsingTextHelper);
recalculateMethod = collapsingTextHelper.getClass().getDeclaredMethod("recalculate");
}
catch (NoSuchFieldException | IllegalAccessException | NoSuchMethodException e) {
collapsingTextHelper = null;
bounds = null;
recalculateMethod = null;
e.printStackTrace();
}
}
private void adjustBounds() {
if (collapsingTextHelper == null) {
return;
}
try {
bounds.left = getEditText().getLeft() + getEditText().getPaddingLeft();
recalculateMethod.invoke(collapsingTextHelper);
}
catch (InvocationTargetException | IllegalAccessException | IllegalArgumentException e) {
e.printStackTrace();
}
}
}
This custom class is a drop-in replacement for the regular TextInputLayout
, and you would use it the same way. For example:
<com.mycompany.myapp.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">
<android.support.design.widget.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.mycompany.myapp.CustomTextInputLayout>
Notes:
In the move to the Material Components library, the field names for the helper class and the bounds have dropped the m
prefix notation. As noted in comments, they are now named collapsingTextHelper
and collapsedBounds
, respectively.
As of API level 28 (Pie), there are certain Restrictions on non-SDK interfaces, including reflection, to access normally inaccessible members in the SDK. However, the various available documents seem to indicate that reflection on components within your own package are not prohibited. As the support library is not part of the platform SDK, and is merged into your package when built, this solution should still be valid. Indeed, recent testing has uncovered no issues, and this still works as expected on the available Pie emulators.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With