Skip to content

Commit

Permalink
[TextInputLayout] Updated cursor color on error for APIs >= 29.
Browse files Browse the repository at this point in the history
Resolves #2719

PiperOrigin-RevId: 472535969
  • Loading branch information
leticiarossi authored and afohrman committed Sep 8, 2022
1 parent 3975a2e commit fbd75ec
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 0 deletions.
19 changes: 19 additions & 0 deletions lib/java/com/google/android/material/color/MaterialColors.java
Expand Up @@ -29,6 +29,7 @@
import androidx.annotation.FloatRange;
import androidx.annotation.IntRange;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import androidx.core.graphics.ColorUtils;
import com.google.android.material.resources.MaterialAttributes;
Expand Down Expand Up @@ -129,6 +130,24 @@ public static ColorStateList getColorStateList(
return resolvedColor == null ? defaultValue : resolvedColor;
}

/**
* Returns the color state list for the provided theme color attribute, or null if the attribute
* is not set in the current theme.
*/
@Nullable
public static ColorStateList getColorStateListOrNull(
@NonNull Context context, @AttrRes int colorAttributeResId) {
TypedValue typedValue = MaterialAttributes.resolve(context, colorAttributeResId);
if (typedValue == null) {
return null;
} else if (typedValue.resourceId != 0) {
return ContextCompat.getColorStateList(context, typedValue.resourceId);
} else if (typedValue.data != 0) {
return ColorStateList.valueOf(typedValue.data);
}
return null;
}

private static int resolveColor(@NonNull Context context, @NonNull TypedValue typedValue) {
if (typedValue.resourceId != 0) {
// Color State List
Expand Down
Expand Up @@ -4206,6 +4206,7 @@ void updateTextInputBoxState() {

final boolean hasFocus = isFocused() || (editText != null && editText.hasFocus());
final boolean isHovered = isHovered() || (editText != null && editText.isHovered());
final boolean isOnError = shouldShowError() || (counterView != null && counterOverflowed);

// Update the text box's stroke color based on the current state.
if (!isEnabled()) {
Expand All @@ -4230,6 +4231,10 @@ void updateTextInputBoxState() {
boxStrokeColor = defaultStrokeColor;
}

if (VERSION.SDK_INT >= VERSION_CODES.Q) {
updateCursorColor(isOnError);
}

endLayout.onTextInputBoxStateUpdated();

refreshStartIconDrawableState();
Expand Down Expand Up @@ -4286,6 +4291,25 @@ private void updateStrokeErrorColor(boolean hasFocus, boolean isHovered) {
}
}

@TargetApi(VERSION_CODES.Q)
private void updateCursorColor(boolean isOnError) {
ColorStateList cursorColor =
MaterialColors.getColorStateListOrNull(getContext(), R.attr.colorControlActivated);
if (editText == null || editText.getTextCursorDrawable() == null || cursorColor == null) {
// If there's no cursor or if its color is null, return.
return;
}

Drawable cursorDrawable = editText.getTextCursorDrawable();
if (isOnError) {
// Use the stroke error color for the cursor error color, or the box stroke color if
// strokeErrorColor is null.
cursorColor =
strokeErrorColor != null ? strokeErrorColor : ColorStateList.valueOf(boxStrokeColor);
}
DrawableCompat.setTintList(cursorDrawable, cursorColor);
}

private void expandHint(boolean animate) {
if (animator != null && animator.isRunning()) {
animator.cancel();
Expand Down

1 comment on commit fbd75ec

@pranavpandey
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now, it no longer allows setting a custom cursor color via:

DrawableCompat.setTintList(getEditText().getTextCursorDrawable(), cursorColor);

It was working fine with 1.7.0-alpha02 and I think it should cache the older tint list before applying the error color.

Please sign in to comment.