Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TextInputLayout hint overlap issue

I'm using TextInputLayout from Android Design Library to show label on EditText.

The problem is when I start activity with that EditText hint (label) text overlaps the actual text (for a second) and only then returns to its own place (at the top of the EditText).

To illustrate this issue I recorded a short sample video: https://youtu.be/gy0CzcYggxU

Here is my activity.xml:

<LinearLayout
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:layout_margin="16dp"
  android:orientation="vertical">

<android.support.design.widget.TextInputLayout
    android:id="@+id/firstNameTextInputLayout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="8dp">

  <EditText
      android:id="@+id/firstNameEditText"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:hint="@string/first_name"
      android:inputType="textCapWords"
      android:textColor="@color/textPrimary"
      android:textColorHint="@color/textSecondary"
      android:textSize="16sp"
      android:theme="@style/CustomEditText"/>
</android.support.design.widget.TextInputLayout>


<android.support.design.widget.TextInputLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="24dp">

  <EditText
      android:id="@+id/lastNameEditText"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:hint="@string/last_name"
      android:inputType="textCapWords"
      android:textColor="@color/textPrimary"
      android:textColorHint="@color/textSecondary"
      android:textSize="16sp"
      android:theme="@style/CustomEditText"/>
</android.support.design.widget.TextInputLayout>

like image 754
Pavlo Zin Avatar asked Jun 15 '15 09:06

Pavlo Zin


2 Answers

I came up with a cheap workaround for this and another bug.

Subclass the TextInputLayout
See code for addView()
If you have text set in the text view when it is inflated it will set the hint to collapsed and prevent an animation. This code performs a workaround that will temporarily set text until the state is set during setup. As a bonus there is code that makes sure the hint gets drawn just in case there is only one layout pass.

    public class TextInputLayout extends android.support.design.widget.TextInputLayout {

    public TextInputLayout(Context context) {
        super(context);
    }

    public TextInputLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @SuppressLint("DrawAllocation")
    @Override
    protected void onLayout(final boolean changed, final int left, final int top, final int right, final int bottom) {
        if (ViewCompat.isLaidOut(this)) {
            super.onLayout(changed, left, top, right, bottom);
        } else {
            // Workaround for this terrible logic where onLayout gets called before the view is flagged as laid out.
            // The normal TextInputLayout is depending on isLaidOut when onLayout is called and failing the check which prevents initial drawing
            // If there are multiple layout passes this doesn't get broken
            post(new Runnable() {
                @SuppressLint("WrongCall")
                @Override
                public void run() {
                    TextInputLayout.super.onLayout(changed, left, top, right, bottom);
                }
            });
        }
    }

    @Override
    public void addView(View child, int index, ViewGroup.LayoutParams params) {
        if (child instanceof EditText) {
            EditText editText = (EditText) child;
            if (StringUtils.isEmpty(editText.getText().toString())) {
                editText.setText("  "); // Set filler text so the initial state of the floating title is to be collapsed
                super.addView(child, index, params);
                editText.setText(""); // Set back to blank to cause the hint to animate in just in case the user sets text
                // This prevents the hint from being drawn over text that is set programmatically before the state is determined
                return;
            }
        }
        super.addView(child, index, params);
    }
}
like image 75
Michael Phaedok Avatar answered Sep 30 '22 03:09

Michael Phaedok


The workaround that worked for me was to update activity like this:

@Override
protected void onCreate(Bundle savedInstanceState) {
    ...
    textInputLayout.setHintAnimationEnabled(false);
    textInput.setText("sample");
    textInputLayout.setHintAnimationEnabled(true);
    ...
}
like image 37
Michał Baran Avatar answered Sep 30 '22 05:09

Michał Baran