material-components / material-components-android

Modular and customizable Material Design UI components for Android
Apache License 2.0
16.42k stars 3.08k forks source link

[TextInputLayout] [Motion] Hint does not follow the layout in animations #1420

Closed kroegerama closed 4 years ago

kroegerama commented 4 years ago

Description: I have some TextInputLayouts in a Fragment and I have set the Animation of my Fragments to MaterialFadeThrough. The Animation runs fine (slightly expanding in width), but the hint label inside the TextInputLayout does not move with the parent container. After tapping one Input, all hints in the view jump to the correct position.

Screenshots Before tapping (after enterTransition with MaterialFadeThrough): image

After focusing the first Input: image

Expected behavior: The hint should move correctly with the outline of the TextInputLayout.

Source code: Layout snippet

    <com.google.android.material.textfield.TextInputLayout
        android:id="@+id/inputFirstName"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginHorizontal="16dp"
        android:layout_marginTop="24dp"
        android:hint="@string/first_name">

        <com.google.android.material.textfield.TextInputEditText
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:inputType="textPersonName" />

    </com.google.android.material.textfield.TextInputLayout>

Style

    <style name="AppStyle.TextInput" parent="Widget.MaterialComponents.TextInputLayout.FilledBox">
        <item name="shapeAppearanceOverlay">?shapeAppearanceMediumComponent</item>
        <item name="materialThemeOverlay">@style/AppStyle.TextInput.Overlay</item>
        <item name="boxBackgroundColor">@color/cardBackground</item>
    </style>

    <style name="AppStyle.TextInput.Overlay" parent="ThemeOverlay.MaterialComponents.TextInputEditText.FilledBox">
        <item name="editTextStyle">@style/AppStyle.EditText</item>
    </style>

    <style name="AppStyle.EditText" parent="Widget.MaterialComponents.TextInputEditText.FilledBox">
        <item name="android:background">@drawable/bg_textinput</item>
        <item name="android:textAppearance">@style/AppTextAppearance</item>
    </style>

Android API version: Android Q

Material Library version: Bug exists on 1.2.0-beta01 and 1.3.0-alpha01

Device: Android Emulator, Pixel 3 XL

dsn5ft commented 4 years ago

I just tried using our Catalog demo app but was unable to reproduce this. Does it only happen with MaterialFadeThrough? Can you try MaterialSharedAxis as a test?

Also can you provide a video? As well as a minimal sample app that reproduces your setup and the issue?

kroegerama commented 4 years ago

I just created a minimal example and could not reproduce the problem at all. But then I added a startIcon to one of the TextInputLayouts and the bug appeared.

So, if one of the TextInputLayouts has a startIcon, all TextInputLayouts (with and without startIcon) are getting this bug. This also happens when I use MaterialSharedAxis with Z-Direction.

You can find the example here: kroegerama/material-components-til-test

And the video here: screen-record.zip

dsn5ft commented 4 years ago

Great, thank you! We'll take a look soon.

dsn5ft commented 4 years ago

Ahh this keeps coming up, probably because it's not very clear behavior from the Android Transitions framework. By default, when setting a transition on a fragment or a sceneRoot, that transition will be applied to each child view as opposed to the fragment as a whole. That behavior might make more sense for some of the framework transitions like Explode which expect to animate all the individual views, but our Material transition patterns typically expect to operate on screens as a whole.

I'm still not exactly sure why the TextInputLayout is behaving that way with a start icon, but you can workaround the issue and also achieve the intended effect by adding android:transitionGroup="true" to the top-level view of the fragment. If you support pre-lollipop, then you can do something like ViewGroupCompat.setTransitionGroup(fragment.getView(), true).

kroegerama commented 4 years ago

Thank you so much! android:transitionGroup="true" did indeed fix this glitch. And today I learned something new about the Android Transitions framework :)

dsn5ft commented 4 years ago

Np, thanks for asking the question! We're updating our docs to make this more clear.