Obsolete
Status Update
Comments
ad...@gmail.com <ad...@gmail.com> #2
Note: Issue doesn't seem to be specific to 'clear_text' endIconMode. It reproduced with 'custom' endIconMode too.
le...@google.com <le...@google.com> #3
Hi, I'm not able to reproduce the issue. Could you provide more code or a simplified version of your app where the issue is seen?
ad...@gmail.com <ad...@gmail.com> #4
I've now just created a new project from Android Studio's 'Empty Activity' template (migrated to AndroidX) and added the 2 TextInputEditText and the issue is reproducing.
I've attached the sample project.
I've attached the sample project.
le...@google.com <le...@google.com> #5
it seems that the issue is caused by setting fillViewport in the ScrollView inside the ConstraintLayout. When not setting fillViewport, or if the ScrollView is not wrapped by a ConstrantLayout the issue isn't reproduced.
Will investigate further.
Will investigate further.
ad...@gmail.com <ad...@gmail.com> #6
Great :) . Thank you
e....@gmail.com <e....@gmail.com> #7
I have content longer than screen height and fillViewport has no effect. It's broken in either case.
I'm using ConstraintLayout in NestedScrollView.
It applies to drop down mode icon as well.
2019-05-19 00:58:31.093 20181-20181/cz.quickjobs.midgard.dev.debug W/View: requestLayout() improperly called by androidx.appcompat.widget.AppCompatAutoCompleteTextView{e0cc38b VFED..CL. ......ID 0,0-312,123 #7f0a014d app:id/---} during layout: running second layout pass
2019-05-19 00:58:31.093 20181-20181/cz.quickjobs.midgard.dev.debug W/View: requestLayout() improperly called by androidx.appcompat.widget.AppCompatAutoCompleteTextView{9820d67 VFED..CL. ......ID 0,0-656,123 #7f0a0147 app:id/---} during layout: running second layout pass
I'm using ConstraintLayout in NestedScrollView.
It applies to drop down mode icon as well.
2019-05-19 00:58:31.093 20181-20181/cz.quickjobs.midgard.dev.debug W/View: requestLayout() improperly called by androidx.appcompat.widget.AppCompatAutoCompleteTextView{e0cc38b VFED..CL. ......ID 0,0-312,123 #7f0a014d app:id/---} during layout: running second layout pass
2019-05-19 00:58:31.093 20181-20181/cz.quickjobs.midgard.dev.debug W/View: requestLayout() improperly called by androidx.appcompat.widget.AppCompatAutoCompleteTextView{9820d67 VFED..CL. ......ID 0,0-656,123 #7f0a0147 app:id/---} during layout: running second layout pass
e....@gmail.com <e....@gmail.com> #8
The attached image captures the stack trace. Here's the interesting bit
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
setEditTextHeightAndDummyDrawables();
}
private void setEditTextHeightAndDummyDrawables() {
// ...
updateIconDummyDrawables();
}
private void updateIconDummyDrawables() {
// ...
// Update end icon drawable if needed.
if (hasEndIcon() && isEndIconVisible()) {
// ...
final Drawable[] compounds = TextViewCompat.getCompoundDrawablesRelative(editText);
// Store the user defined end compound drawable so that we can restore it later.
if (compounds[2] != endIconDummyDrawable) {
originalEditTextEndDrawable = compounds[2];
// The statement below should probably be here instead.
}
TextViewCompat.setCompoundDrawablesRelative(
editText, compounds[0], compounds[1], endIconDummyDrawable, compounds[3]); // <<<<<<<<< This statement.
} else if (endIconDummyDrawable != null) {
// Remove the dummy end compound drawable if it exists and clear it.
final Drawable[] compounds = TextViewCompat.getCompoundDrawablesRelative(editText);
if (compounds[2] == endIconDummyDrawable) {
TextViewCompat.setCompoundDrawablesRelative(
editText, compounds[0], compounds[1], originalEditTextEndDrawable, compounds[3]);
}
endIconDummyDrawable = null;
}
}
public void TextView.setCompoundDrawablesRelative(@Nullable Drawable start, @Nullable Drawable top,
@Nullable Drawable end, @Nullable Drawable bottom) {
// ...
requestLayout();
}
It's a vicious cycle. setCompoundDrawables should only be called if they actually changed. I.e. only if the end drawable isn't dummy, set it to dummy.
Also attached is a class implementing a workaround suggested above. It only supports the end icon.
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
setEditTextHeightAndDummyDrawables();
}
private void setEditTextHeightAndDummyDrawables() {
// ...
updateIconDummyDrawables();
}
private void updateIconDummyDrawables() {
// ...
// Update end icon drawable if needed.
if (hasEndIcon() && isEndIconVisible()) {
// ...
final Drawable[] compounds = TextViewCompat.getCompoundDrawablesRelative(editText);
// Store the user defined end compound drawable so that we can restore it later.
if (compounds[2] != endIconDummyDrawable) {
originalEditTextEndDrawable = compounds[2];
// The statement below should probably be here instead.
}
TextViewCompat.setCompoundDrawablesRelative(
editText, compounds[0], compounds[1], endIconDummyDrawable, compounds[3]); // <<<<<<<<< This statement.
} else if (endIconDummyDrawable != null) {
// Remove the dummy end compound drawable if it exists and clear it.
final Drawable[] compounds = TextViewCompat.getCompoundDrawablesRelative(editText);
if (compounds[2] == endIconDummyDrawable) {
TextViewCompat.setCompoundDrawablesRelative(
editText, compounds[0], compounds[1], originalEditTextEndDrawable, compounds[3]);
}
endIconDummyDrawable = null;
}
}
public void TextView.setCompoundDrawablesRelative(@Nullable Drawable start, @Nullable Drawable top,
@Nullable Drawable end, @Nullable Drawable bottom) {
// ...
requestLayout();
}
It's a vicious cycle. setCompoundDrawables should only be called if they actually changed. I.e. only if the end drawable isn't dummy, set it to dummy.
Also attached is a class implementing a workaround suggested above. It only supports the end icon.
le...@google.com <le...@google.com> #9
Hi, this has been fixed internally and should be synced out to GitHub this week. The setCompoundDrawablesRelative call should indeed only happen if the dummy drawable is not already set.
eg...@gmail.com <eg...@gmail.com> #11
Still happening in 'com.google.android.material:material:1.1.0-alpha07'
requestLayout() improperly called by com.google.android.material.textfield.TextInputEditText{b5ff04f VFED..CL. ......ID 0,0-704,89 #7f08013b app:id/user_login} during layout: running second layout pass
requestLayout() improperly called by com.google.android.material.textfield.TextInputEditText{b6ac7f3 VFED..CL. ........ 0,0-704,89 #7f0800c4 app:id/password_login} during second layout pass: posting in next frame
I have this in my XML:
<com.google.android.material.textfield.TextInputLayout
style="@style/TextInputLayoutAppearance"
android:id="@+id/text_input_layout_user_login"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintHorizontal_bias="0.0"
android:layout_marginBottom="8dp"
app:boxBackgroundColor="@color/backgroundLogin"
app:layout_constraintBottom_toTopOf="@+id/text_input_layout_password_login"
app:errorTextColor="#FF0000"
app:startIconDrawable="@drawable/round_account_circle_white_24"
app:startIconTint="@color/white"
android:hint="@string/user_login"
android:layout_marginTop="8dp">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/user_login"
android:textSize="14sp"
android:textColor="@color/white"
android:textColorHint="@color/white"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textNoSuggestions"/>
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
style="@style/TextInputLayoutAppearance"
android:id="@+id/text_input_layout_password_login"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintBottom_toTopOf="@+id/error_text_login"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
app:layout_constraintHorizontal_bias="0.0"
app:boxBackgroundColor="@color/backgroundLogin"
app:errorTextColor="#FF0000"
app:startIconDrawable="@drawable/round_vpn_key_white_24"
app:startIconTint="@color/white"
app:endIconTint="@color/white"
android:hint="@string/password_login"
app:endIconMode="password_toggle">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/password_login"
android:textColor="@color/white"
android:textSize="14sp"
android:textColorHint="@color/white"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPassword"
app:passwordToggleEnabled="true"/>
</com.google.android.material.textfield.TextInputLayout>
requestLayout() improperly called by com.google.android.material.textfield.TextInputEditText{b5ff04f VFED..CL. ......ID 0,0-704,89 #7f08013b app:id/user_login} during layout: running second layout pass
requestLayout() improperly called by com.google.android.material.textfield.TextInputEditText{b6ac7f3 VFED..CL. ........ 0,0-704,89 #7f0800c4 app:id/password_login} during second layout pass: posting in next frame
I have this in my XML:
<com.google.android.material.textfield.TextInputLayout
style="@style/TextInputLayoutAppearance"
android:id="@+id/text_input_layout_user_login"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintHorizontal_bias="0.0"
android:layout_marginBottom="8dp"
app:boxBackgroundColor="@color/backgroundLogin"
app:layout_constraintBottom_toTopOf="@+id/text_input_layout_password_login"
app:errorTextColor="#FF0000"
app:startIconDrawable="@drawable/round_account_circle_white_24"
app:startIconTint="@color/white"
android:hint="@string/user_login"
android:layout_marginTop="8dp">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/user_login"
android:textSize="14sp"
android:textColor="@color/white"
android:textColorHint="@color/white"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textNoSuggestions"/>
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
style="@style/TextInputLayoutAppearance"
android:id="@+id/text_input_layout_password_login"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintBottom_toTopOf="@+id/error_text_login"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
app:layout_constraintHorizontal_bias="0.0"
app:boxBackgroundColor="@color/backgroundLogin"
app:errorTextColor="#FF0000"
app:startIconDrawable="@drawable/round_vpn_key_white_24"
app:startIconTint="@color/white"
app:endIconTint="@color/white"
android:hint="@string/password_login"
app:endIconMode="password_toggle">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/password_login"
android:textColor="@color/white"
android:textSize="14sp"
android:textColorHint="@color/white"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPassword"
app:passwordToggleEnabled="true"/>
</com.google.android.material.textfield.TextInputLayout>
e....@gmail.com <e....@gmail.com> #12
It doesn't happen to me anymore, but I only use end icons.
Here, TextInputLayout:2711, spot the difference:
/*
* We need to add a dummy drawable as the start and/or end compound drawables so that the text is
* indented and doesn't display below the icon views.
*/
private void updateIconDummyDrawables() {
if (editText == null) {
return;
}
// Update start icon drawable if needed.
if (hasStartIcon() && isStartIconVisible()) {
startIconDummyDrawable = new ColorDrawable();
int right =
startIconView.getMeasuredWidth()
- editText.getPaddingLeft()
+ MarginLayoutParamsCompat.getMarginEnd(
((MarginLayoutParams) startIconView.getLayoutParams()));
startIconDummyDrawable.setBounds(0, 0, right, 1);
final Drawable[] compounds = TextViewCompat.getCompoundDrawablesRelative(editText);
TextViewCompat.setCompoundDrawablesRelative(
editText, startIconDummyDrawable, compounds[1], compounds[2], compounds[3]);
} else if (startIconDummyDrawable != null) {
// Remove the dummy start compound drawable if it exists and clear it.
final Drawable[] compounds = TextViewCompat.getCompoundDrawablesRelative(editText);
TextViewCompat.setCompoundDrawablesRelative(
editText, null, compounds[1], compounds[2], compounds[3]);
startIconDummyDrawable = null;
}
// Update end icon drawable if needed.
if (hasEndIcon() && isEndIconVisible()) {
if (endIconDummyDrawable == null) {
endIconDummyDrawable = new ColorDrawable();
int right =
endIconView.getMeasuredWidth()
- editText.getPaddingRight()
+ MarginLayoutParamsCompat.getMarginStart(
((MarginLayoutParams) endIconView.getLayoutParams()));
endIconDummyDrawable.setBounds(0, 0, right, 1);
}
final Drawable[] compounds = TextViewCompat.getCompoundDrawablesRelative(editText);
// Store the user defined end compound drawable so that we can restore it later.
if (compounds[2] != endIconDummyDrawable) {
originalEditTextEndDrawable = compounds[2];
TextViewCompat.setCompoundDrawablesRelative(
editText, compounds[0], compounds[1], endIconDummyDrawable, compounds[3]);
}
} else if (endIconDummyDrawable != null) {
// Remove the dummy end compound drawable if it exists and clear it.
final Drawable[] compounds = TextViewCompat.getCompoundDrawablesRelative(editText);
if (compounds[2] == endIconDummyDrawable) {
TextViewCompat.setCompoundDrawablesRelative(
editText, compounds[0], compounds[1], originalEditTextEndDrawable, compounds[3]);
}
endIconDummyDrawable = null;
}
}
Here, TextInputLayout:2711, spot the difference:
/*
* We need to add a dummy drawable as the start and/or end compound drawables so that the text is
* indented and doesn't display below the icon views.
*/
private void updateIconDummyDrawables() {
if (editText == null) {
return;
}
// Update start icon drawable if needed.
if (hasStartIcon() && isStartIconVisible()) {
startIconDummyDrawable = new ColorDrawable();
int right =
startIconView.getMeasuredWidth()
- editText.getPaddingLeft()
+ MarginLayoutParamsCompat.getMarginEnd(
((MarginLayoutParams) startIconView.getLayoutParams()));
startIconDummyDrawable.setBounds(0, 0, right, 1);
final Drawable[] compounds = TextViewCompat.getCompoundDrawablesRelative(editText);
TextViewCompat.setCompoundDrawablesRelative(
editText, startIconDummyDrawable, compounds[1], compounds[2], compounds[3]);
} else if (startIconDummyDrawable != null) {
// Remove the dummy start compound drawable if it exists and clear it.
final Drawable[] compounds = TextViewCompat.getCompoundDrawablesRelative(editText);
TextViewCompat.setCompoundDrawablesRelative(
editText, null, compounds[1], compounds[2], compounds[3]);
startIconDummyDrawable = null;
}
// Update end icon drawable if needed.
if (hasEndIcon() && isEndIconVisible()) {
if (endIconDummyDrawable == null) {
endIconDummyDrawable = new ColorDrawable();
int right =
endIconView.getMeasuredWidth()
- editText.getPaddingRight()
+ MarginLayoutParamsCompat.getMarginStart(
((MarginLayoutParams) endIconView.getLayoutParams()));
endIconDummyDrawable.setBounds(0, 0, right, 1);
}
final Drawable[] compounds = TextViewCompat.getCompoundDrawablesRelative(editText);
// Store the user defined end compound drawable so that we can restore it later.
if (compounds[2] != endIconDummyDrawable) {
originalEditTextEndDrawable = compounds[2];
TextViewCompat.setCompoundDrawablesRelative(
editText, compounds[0], compounds[1], endIconDummyDrawable, compounds[3]);
}
} else if (endIconDummyDrawable != null) {
// Remove the dummy end compound drawable if it exists and clear it.
final Drawable[] compounds = TextViewCompat.getCompoundDrawablesRelative(editText);
if (compounds[2] == endIconDummyDrawable) {
TextViewCompat.setCompoundDrawablesRelative(
editText, compounds[0], compounds[1], originalEditTextEndDrawable, compounds[3]);
}
endIconDummyDrawable = null;
}
}
yo...@gmail.com <yo...@gmail.com> #13
same
2019-06-24 18:14:40.863 2872-2872/com.scodeid.scholarshipexpertscodeidev2019 W/View: requestLayout() improperly called by com.google.android.material.textfield.TextInputEditText{b7a2d2f VFED..CL. ......ID 0,0-688,100 #7f0900a8 app:id/input_edit_height_value} during layout: running second layout pass
2019-06-24 18:14:41.125 2872-2872/com.scodeid.scholarshipexpertscodeidev2019 D/MainUnitTestingActivity: onStart
2019-06-24 18:14:41.126 2872-2872/com.scodeid.scholarshipexpertscodeidev2019 D/MainUnitTestingActivity: calculate with onDestroy
2019-06-24 18:14:42.314 2872-2872/com.scodeid.scholarshipexpertscodeidev2019 W/View: requestLayout() improperly called by com.google.android.material.textfield.TextInputEditText{41c9f0e VFED..CL. .F....ID 0,0-688,100 #7f0900aa app:id/input_edit_width_value} during second layout pass: posting in next
2019-06-24 18:14:40.863 2872-2872/com.scodeid.scholarshipexpertscodeidev2019 W/View: requestLayout() improperly called by com.google.android.material.textfield.TextInputEditText{b7a2d2f VFED..CL. ......ID 0,0-688,100 #7f0900a8 app:id/input_edit_height_value} during layout: running second layout pass
2019-06-24 18:14:41.125 2872-2872/com.scodeid.scholarshipexpertscodeidev2019 D/MainUnitTestingActivity: onStart
2019-06-24 18:14:41.126 2872-2872/com.scodeid.scholarshipexpertscodeidev2019 D/MainUnitTestingActivity: calculate with onDestroy
2019-06-24 18:14:42.314 2872-2872/com.scodeid.scholarshipexpertscodeidev2019 W/View: requestLayout() improperly called by com.google.android.material.textfield.TextInputEditText{41c9f0e VFED..CL. .F....ID 0,0-688,100 #7f0900aa app:id/input_edit_width_value} during second layout pass: posting in next
ga...@gmail.com <ga...@gmail.com> #14
Happened to me too, even in alpha09
W/View: requestLayout() improperly called by com.google.android.material.textfield.TextInputEditText{69ada9a VFED..CL. .F...... 0,0-984,153 #7f0901c0 app:id/textFieldEditText} during second layout pass: posting in next frame
2019-08-07 10:49:45.569 25980-25980
W/View: requestLayout() improperly called by androidx.appcompat.widget.AppCompatAutoCompleteTextView{413f432 VFED..CL. ......ID 0,0-984,161 #7f090051 app:id/autoCompleteTextView} during layout: running second layout pass
2019-08-07 10:49:45.570 25980-25980
W/View: requestLayout() improperly called by com.google.android.material.textfield.TextInputEditText{c955300 VFED..CL. ......ID 0,0-984,161 #7f0901c0 app:id/textFieldEditText} during layout: running second layout pass
2019-08-07 10:49:45.570 25980-25980
W/View: requestLayout() improperly called by com.google.android.material.textfield.TextInputEditText
W/View: requestLayout() improperly called by com.google.android.material.textfield.TextInputEditText{69ada9a VFED..CL. .F...... 0,0-984,153 #7f0901c0 app:id/textFieldEditText} during second layout pass: posting in next frame
2019-08-07 10:49:45.569 25980-25980
W/View: requestLayout() improperly called by androidx.appcompat.widget.AppCompatAutoCompleteTextView{413f432 VFED..CL. ......ID 0,0-984,161 #7f090051 app:id/autoCompleteTextView} during layout: running second layout pass
2019-08-07 10:49:45.570 25980-25980
W/View: requestLayout() improperly called by com.google.android.material.textfield.TextInputEditText{c955300 VFED..CL. ......ID 0,0-984,161 #7f0901c0 app:id/textFieldEditText} during layout: running second layout pass
2019-08-07 10:49:45.570 25980-25980
W/View: requestLayout() improperly called by com.google.android.material.textfield.TextInputEditText
le...@google.com <le...@google.com> #15
Reopening this to investigate why the issue still happens
kh...@gmail.com <kh...@gmail.com> #16
Any updates?
st...@google.com <st...@google.com> #17
Material for Android does not actively monitor this Issue Tracker, and we will be closing these issues as obsolete.
If you believe the issue is still affecting your project, please file a new issue athttps://github.com/material-components/material-components-android/issues .
Please be sure that the issue is reproducible using the latest version of the Material library, themes, and styles, and make sure to provide all relevant repro information (steps, screenshots, and a video).
Thank you.
If you believe the issue is still affecting your project, please file a new issue at
Please be sure that the issue is reproducible using the latest version of the Material library, themes, and styles, and make sure to provide all relevant repro information (steps, screenshots, and a video).
Thank you.
Description
Have a layout containing two TextInputEditTexts, both having set app:endIconMode="clear_text".
Write some text in the first TextInputEditText triggering the end icon to appear.
Now write some text in the second TextInputEditText triggering the corresponding end icon to appear.
Observe console log.
- Expected behavior: log contains no errors or warnings
- Actual behavior: log is flooded with messages like:
W/View: requestLayout() improperly called by com.google.android.material.textfield.TextInputEditText{2a57b45 VFED..CL. .F....ID 0,0-1002,147 #7f09008d app:id/id1} during layout: running second layout pass
W/View: requestLayout() improperly called by com.google.android.material.textfield.TextInputEditText{4d9544c VFED..CL. ......ID 0,0-1002,147 #7f09008c app:id/id2} during layout: running second layout pass
W/View: requestLayout() improperly called by com.google.android.material.textfield.TextInputEditText{2a57b45 VFED..CL. .F...... 0,0-1002,147 #7f09008d app:id/id1} during second layout pass: posting in next frame
W/View: requestLayout() improperly called by com.google.android.material.textfield.TextInputEditText{4d9544c VFED..CL. ......ID 0,0-1002,147 #7f09008c app:id/id2} during layout: running second layout pass
- Source code:
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/id1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:endIconMode="clear_text"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox">
<com.google.android.material.textfield.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textCapWords" />
</com.google.android.material.textfield.TextInputLayout>
- Design Library Version: 1.1.0-alpha06
- Android API version: 28
- Device: Pixel 2 Emulator and Samsung S8