Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Change TextInputLayout floating hint position to middle?

Tags:

android

xml

How can I change TextInputLayout floating hint position to middle?

I've read this answer and others about the same subject but they're over a year old.

I'm asking this question to see if there are any changes in 2017.

like image 241
Jonathan Doe Avatar asked Jul 19 '17 21:07

Jonathan Doe


1 Answers

The behavior that you want exists inside the CollapsingTextHelper class. Unfortunately, this class is package-private and final, so there's no officially supported way for you to call the methods you'd like. Here's what you'd love to be able to write:

private void setCollapsedHintMiddle(TextInputLayout layout) {
    CollapsingTextHelper helper = layout.getCollapsingTextHelper();
    helper.setCollapsedTextGravity(Gravity.TOP | Gravity.CENTER_HORIZONTAL);
}

Since you can't do it that way, you can hack around it using reflection:

private void setCollapsedHintMiddle(TextInputLayout layout) {
    try {
        Field helperField = TextInputLayout.class.getDeclaredField("mCollapsingTextHelper");
        helperField.setAccessible(true);
        Object helper = helperField.get(layout);

        Method setterMethod = helper.getClass().getDeclaredMethod("setCollapsedTextGravity", int.class);
        setterMethod.setAccessible(true);
        setterMethod.invoke(helper, Gravity.TOP | Gravity.CENTER_HORIZONTAL);
    }
    catch (NoSuchFieldException e) {
        // TODO
    }
    catch (IllegalAccessException e) {
        // TODO
    }
    catch (NoSuchMethodException e) {
        // TODO
    }
    catch (InvocationTargetException e) {
        // TODO
    }
}

Note that this relies on the internal implementation details of both TextInputLayout and CollapsingTextHelper, and could break at any time.

Edit

As I alluded to in my comment on the original question, there's an officially-supported way to do something that is not quite what you want. If you declare your TextInputLayout like this:

<android.support.design.widget.TextInputLayout
    android:id="@+id/email"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <android.support.design.widget.TextInputEditText
        android:id="@+id/emailChild"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center_horizontal"
        android:hint="Email"/>

</android.support.design.widget.TextInputLayout>

And then in Java update the TextInputEditText's gravity:

    EditText emailChild = (EditText) findViewById(R.id.emailChild);
    emailChild.setGravity(Gravity.START);

The resulting behavior will be that the hint is displayed horizontally centered (both when the view has focus/text and when it does not) while the user-entered text is displayed on the left.

like image 64
Ben P. Avatar answered Sep 30 '22 05:09

Ben P.