material-components-android icon indicating copy to clipboard operation
material-components-android copied to clipboard

[TextInputLayout] TextInputLayout wrong minimum height

Open zhanghai opened this issue 10 months ago • 1 comments

Description: TextInputLayout.updateEditTextHeightBasedOnIcon() may set a wrong minimum height that lingers around. This is basically another way to reproduce #3451 where 4a2654a didn't fix the issue.

Expected behavior: TextInputLayout should resize with text.

Source code: The code snippet which is causing this issue

https://github.com/material-components/material-components-android/blob/9393b9779e244cbd7c78522fd1282aed73cb8d33/lib/java/com/google/android/material/textfield/TextInputLayout.java#L3310-L3325

It only ever sets the minimum height but doesn't reset it. And in case the EndCompoundLayout becomes GONE due to icon becoming hidden, the EndCompoundLayout won't participate in the next layout and thus EndCompoundLayout.getMeasuredHeight() would return a stale height.

The fix in 4a2654a used a TextWatcher to reset the minimum height, however it won't work if the EndCompoundLayout is becoming GONE after the text change, e.g. when the app removes the error state (and thus removing the error icon), before re-layout for the previous text change happened.

It seems to me the code in updateEditTextHeightBasedOnIcon() should inspect the visibility of EndCompoundLayout before using its measured height, and manually use 0 in the case EndCompoundLayout is GONE. It should also reset the minimum height when measure height of EndCompoundLayout is smaller and the minimum height of the edit text is different (this way we prevent loops).

Minimal sample app repro:

Something along the following lines:

textInputEditText.setText("a\nb\nc\nd")
textInputLayout.error = "error"
// Wait for layout and draw then in a separate place...
textInputEditText.setText("a")
textInputLayout.error = null

An actual example can be found at https://github.com/zhanghai/MaterialFiles/commit/10a67dde749d64a7549cb97ad4ff4c00f6ad3e65 and its APK artifact, by opening the file manager app, opening properties of a regular file and go to the checksum tab, put a multi-line inconsistent checksum (e.g. copy-pasting SHA-256 sum twice) into the "Compare" edit text and then clear the edit text.

Android API version: Android 14

Material Library version: 1.11.0 and 1.12.0-rc01

Device: Android Emulator Pixel 2 Android 14

zhanghai avatar Apr 17 '24 10:04 zhanghai

@pekingme could you take a look at this as you worked on https://github.com/material-components/material-components-android/commit/4a2654a3f389d44f7f7d76da30472c2bc0163ef6 thanks!

paulfthomas avatar Apr 17 '24 21:04 paulfthomas