Skip to content

Commit 4044183

Browse files
drchenveganafro
authored andcommitted
[TextInputLayout] Apply tint when setting start icons
If startIconTint is a plain color, refreshStartIconDrawableState() won't update the tint to the new drawable. To solve the issue and make the logic be consistent, calls applyStartIconTint() when a new icon is set. Resolves #2141 PiperOrigin-RevId: 383632467
1 parent 456f135 commit 4044183

File tree

3 files changed

+75
-1
lines changed

3 files changed

+75
-1
lines changed

lib/java/com/google/android/material/textfield/TextInputLayout.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3107,6 +3107,7 @@ public void setStartIconDrawable(@DrawableRes int resId) {
31073107
public void setStartIconDrawable(@Nullable Drawable startIconDrawable) {
31083108
startIconView.setImageDrawable(startIconDrawable);
31093109
if (startIconDrawable != null) {
3110+
applyStartIconTint();
31103111
setStartIconVisible(true);
31113112
refreshStartIconDrawableState();
31123113
} else {
@@ -3461,7 +3462,10 @@ public void setEndIconDrawable(@DrawableRes int resId) {
34613462
*/
34623463
public void setEndIconDrawable(@Nullable Drawable endIconDrawable) {
34633464
endIconView.setImageDrawable(endIconDrawable);
3464-
refreshEndIconDrawableState();
3465+
if (endIconDrawable != null) {
3466+
applyEndIconTint();
3467+
refreshEndIconDrawableState();
3468+
}
34653469
}
34663470

34673471
/**

tests/javatests/com/google/android/material/testutils/TextInputLayoutActions.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
import android.content.res.ColorStateList;
2222
import android.graphics.Color;
23+
import android.graphics.PorterDuff;
2324
import android.graphics.Typeface;
2425
import android.graphics.drawable.ColorDrawable;
2526
import android.graphics.drawable.Drawable;
@@ -424,6 +425,26 @@ public void perform(UiController uiController, View view) {
424425
};
425426
}
426427

428+
public static ViewAction setStartIconTintMode(final PorterDuff.Mode tintMode) {
429+
return new ViewAction() {
430+
@Override
431+
public Matcher<View> getConstraints() {
432+
return isAssignableFrom(TextInputLayout.class);
433+
}
434+
435+
@Override
436+
public String getDescription() {
437+
return "Set tint mode for the start icon";
438+
}
439+
440+
@Override
441+
public void perform(UiController uiController, View view) {
442+
TextInputLayout layout = (TextInputLayout) view;
443+
layout.setStartIconTintMode(tintMode);
444+
}
445+
};
446+
}
447+
427448
public static ViewAction setStartIconOnClickListener(final OnClickListener onClickListener) {
428449
return new ViewAction() {
429450
@Override

tests/javatests/com/google/android/material/textfield/TextInputLayoutIconsTest.java

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
import static com.google.android.material.testutils.TextInputLayoutActions.setStartIconOnClickListener;
4646
import static com.google.android.material.testutils.TextInputLayoutActions.setStartIconOnLongClickListener;
4747
import static com.google.android.material.testutils.TextInputLayoutActions.setStartIconTintList;
48+
import static com.google.android.material.testutils.TextInputLayoutActions.setStartIconTintMode;
4849
import static com.google.android.material.testutils.TextInputLayoutActions.setSuffixText;
4950
import static com.google.android.material.testutils.TextInputLayoutActions.setTransformationMethod;
5051
import static com.google.android.material.testutils.TextInputLayoutMatchers.doesNotShowEndIcon;
@@ -53,6 +54,7 @@
5354
import static com.google.android.material.testutils.TextInputLayoutMatchers.endIconIsChecked;
5455
import static com.google.android.material.testutils.TextInputLayoutMatchers.endIconIsNotChecked;
5556
import static com.google.android.material.testutils.TextInputLayoutMatchers.showsEndIcon;
57+
import static com.google.common.truth.Truth.assertThat;
5658
import static org.hamcrest.Matchers.allOf;
5759
import static org.hamcrest.Matchers.not;
5860
import static org.junit.Assert.assertEquals;
@@ -62,13 +64,17 @@
6264
import static org.junit.Assert.assertTrue;
6365

6466
import android.app.Activity;
67+
import android.content.res.ColorStateList;
6568
import android.graphics.Color;
69+
import android.graphics.PorterDuff;
6670
import android.graphics.drawable.ColorDrawable;
6771
import android.graphics.drawable.Drawable;
72+
import androidx.core.graphics.drawable.TintAwareDrawable;
6873
import android.text.method.PasswordTransformationMethod;
6974
import android.text.method.TransformationMethod;
7075
import android.view.KeyEvent;
7176
import android.widget.EditText;
77+
import androidx.annotation.Nullable;
7278
import androidx.test.espresso.ViewAssertion;
7379
import androidx.test.espresso.matcher.ViewMatchers.Visibility;
7480
import androidx.test.filters.LargeTest;
@@ -525,6 +531,30 @@ public void testSetStartIconProgrammatically() {
525531
assertEquals(contentDesc, textInputLayout.getStartIconContentDescription().toString());
526532
}
527533

534+
@Test
535+
public void testSetStartIconTint() {
536+
final Activity activity = activityTestRule.getActivity();
537+
final TextInputLayout textInputLayout = activity.findViewById(R.id.textinput_no_icon);
538+
Drawable drawable = new TintCapturedDrawable();
539+
540+
// Set start icon
541+
onView(withId(R.id.textinput_no_icon)).perform(
542+
setStartIconTintList(ColorStateList.valueOf(Color.RED)));
543+
onView(withId(R.id.textinput_no_icon)).perform(setStartIconTintMode(PorterDuff.Mode.MULTIPLY));
544+
onView(withId(R.id.textinput_no_icon)).perform(setStartIcon(drawable));
545+
546+
// Assert the start icon's tint is set
547+
assertNotNull(textInputLayout.getStartIconDrawable());
548+
assertThat(textInputLayout.getStartIconDrawable()).isInstanceOf(TintCapturedDrawable.class);
549+
assertEquals(
550+
Color.RED,
551+
((TintCapturedDrawable) textInputLayout.getStartIconDrawable())
552+
.capturedTint.getDefaultColor());
553+
assertEquals(
554+
PorterDuff.Mode.MULTIPLY,
555+
((TintCapturedDrawable) textInputLayout.getStartIconDrawable()).capturedTintMode);
556+
}
557+
528558
@Test
529559
public void testStartIconDisables() {
530560
// Disable the start icon
@@ -876,4 +906,23 @@ private static ViewAssertion isPasswordToggledVisible(final boolean isToggledVis
876906
}
877907
};
878908
}
909+
910+
private static class TintCapturedDrawable extends ColorDrawable implements TintAwareDrawable {
911+
ColorStateList capturedTint;
912+
PorterDuff.Mode capturedTintMode;
913+
914+
TintCapturedDrawable() {
915+
super(Color.WHITE);
916+
}
917+
918+
@Override
919+
public void setTintList(@Nullable ColorStateList tint) {
920+
capturedTint = tint;
921+
}
922+
923+
@Override
924+
public void setTintMode(@Nullable PorterDuff.Mode tintMode) {
925+
capturedTintMode = tintMode;
926+
}
927+
}
879928
}

0 commit comments

Comments
 (0)