From 442c02dc34ef0b5af872fd76a83fdf07fe31c514 Mon Sep 17 00:00:00 2001 From: Michelle Brubaker Date: Thu, 11 Mar 2021 19:55:46 -0500 Subject: [PATCH 1/6] Allow the user to set the EditText color. --- stripe/api/stripe.api | 1 + .../com/stripe/android/view/StripeEditText.kt | 14 +++++++--- .../stripe/android/view/StripeEditTextTest.kt | 27 +++++++++++++++++++ 3 files changed, 38 insertions(+), 4 deletions(-) diff --git a/stripe/api/stripe.api b/stripe/api/stripe.api index 754685d663e..767082b4abf 100644 --- a/stripe/api/stripe.api +++ b/stripe/api/stripe.api @@ -5820,6 +5820,7 @@ public class com/stripe/android/view/StripeEditText : com/google/android/materia public final fun setErrorMessageListener (Lcom/stripe/android/view/StripeEditText$ErrorMessageListener;)V protected final fun setLastKeyDelete (Z)V public final fun setShouldShowError (Z)V + public fun setTextColor (Landroid/content/res/ColorStateList;)V } public abstract interface class com/stripe/android/view/StripeEditText$AfterTextChangedListener { diff --git a/stripe/src/main/java/com/stripe/android/view/StripeEditText.kt b/stripe/src/main/java/com/stripe/android/view/StripeEditText.kt index 8b47c74d160..2ddd672890d 100644 --- a/stripe/src/main/java/com/stripe/android/view/StripeEditText.kt +++ b/stripe/src/main/java/com/stripe/android/view/StripeEditText.kt @@ -30,7 +30,7 @@ open class StripeEditText @JvmOverloads constructor( private var afterTextChangedListener: AfterTextChangedListener? = null private var deleteEmptyListener: DeleteEmptyListener? = null - var cachedColorStateList: ColorStateList? = null + var cachedColorStateList: ColorStateList private set /** @@ -89,12 +89,19 @@ open class StripeEditText @JvmOverloads constructor( maxLines = 1 listenForTextChanges() listenForDeleteEmpty() - determineDefaultErrorColor() cachedColorStateList = textColors + determineDefaultErrorColor() } protected open val accessibilityText: String? = null + override fun setTextColor(colors: ColorStateList?) { + super.setTextColor(colors) + + // This will only use textColors and not colors because textColor is never null + cachedColorStateList = textColors + } + override fun onCreateInputConnection(outAttrs: EditorInfo): InputConnection? { val inputConnection = super.onCreateInputConnection(outAttrs) return inputConnection?.let { @@ -146,10 +153,9 @@ open class StripeEditText @JvmOverloads constructor( } private fun determineDefaultErrorColor() { - cachedColorStateList = textColors defaultErrorColor = ContextCompat.getColor( context, - if (StripeColorUtils.isColorDark(textColors.defaultColor)) { + if (StripeColorUtils.isColorDark(cachedColorStateList.defaultColor)) { // Note: if the _text_ color is dark, then this is a // light theme, and vice-versa. R.color.stripe_error_text_light_theme diff --git a/stripe/src/test/java/com/stripe/android/view/StripeEditTextTest.kt b/stripe/src/test/java/com/stripe/android/view/StripeEditTextTest.kt index 75b16d35746..ef21c9463b2 100644 --- a/stripe/src/test/java/com/stripe/android/view/StripeEditTextTest.kt +++ b/stripe/src/test/java/com/stripe/android/view/StripeEditTextTest.kt @@ -1,6 +1,7 @@ package com.stripe.android.view import android.content.Context +import android.content.res.ColorStateList import androidx.annotation.ColorInt import androidx.appcompat.view.ContextThemeWrapper import androidx.core.content.ContextCompat @@ -104,6 +105,32 @@ internal class StripeEditTextTest { .isEqualTo(blueError) } + @Test + fun setTextColor() { + editText.setTextColor( + ColorStateList.valueOf( + ContextCompat.getColor( + context, + android.R.color.holo_red_dark + ) + ) + ) + + // The field state must be toggled to show an error + editText.shouldShowError = true + editText.shouldShowError = false + + assertThat(editText.textColors) + .isEqualTo( + ColorStateList.valueOf( + ContextCompat.getColor( + context, + android.R.color.holo_red_dark + ) + ) + ) + } + @Test fun getCachedColorStateList_afterInit_returnsNotNull() { assertThat(editText.cachedColorStateList) From 2b1f25dccc12da7621cbd04082edbf850e7ee44f Mon Sep 17 00:00:00 2001 From: Michelle Brubaker Date: Thu, 18 Mar 2021 17:35:47 -0400 Subject: [PATCH 2/6] Small fixes --- .../java/com/stripe/android/view/StripeEditText.kt | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/stripe/src/main/java/com/stripe/android/view/StripeEditText.kt b/stripe/src/main/java/com/stripe/android/view/StripeEditText.kt index 2ddd672890d..f34d06305c8 100644 --- a/stripe/src/main/java/com/stripe/android/view/StripeEditText.kt +++ b/stripe/src/main/java/com/stripe/android/view/StripeEditText.kt @@ -48,9 +48,9 @@ open class StripeEditText @JvmOverloads constructor( if (field != shouldShowError) { // only update the view's UI if the property's value is changing if (shouldShowError) { - setTextColor(errorColor ?: defaultErrorColor) + super.setTextColor(errorColor ?: defaultErrorColor) } else { - setTextColor(cachedColorStateList) + super.setTextColor(cachedColorStateList) } refreshDrawableState() } @@ -102,6 +102,13 @@ open class StripeEditText @JvmOverloads constructor( cachedColorStateList = textColors } + override fun setTextColor(color: Int) { + super.setTextColor(color) + + // This will only use textColors and not colors because textColor is never null + cachedColorStateList = ColorStateList.valueOf(color) + } + override fun onCreateInputConnection(outAttrs: EditorInfo): InputConnection? { val inputConnection = super.onCreateInputConnection(outAttrs) return inputConnection?.let { From 1f9469692467fe5cb8db05ce01752a599f2b9e59 Mon Sep 17 00:00:00 2001 From: Michelle Brubaker Date: Thu, 18 Mar 2021 20:17:37 -0400 Subject: [PATCH 3/6] Create external color and error color variables, and make behavior consistent with error processing. --- stripe/api/stripe.api | 3 +- .../com/stripe/android/view/StripeEditText.kt | 28 +++++++++---------- .../stripe/android/view/StripeEditTextTest.kt | 2 +- 3 files changed, 17 insertions(+), 16 deletions(-) diff --git a/stripe/api/stripe.api b/stripe/api/stripe.api index 057322e0e5e..5e952b00023 100644 --- a/stripe/api/stripe.api +++ b/stripe/api/stripe.api @@ -5859,7 +5859,7 @@ public class com/stripe/android/view/StripeEditText : com/google/android/materia public fun (Landroid/content/Context;Landroid/util/AttributeSet;I)V public synthetic fun (Landroid/content/Context;Landroid/util/AttributeSet;IILkotlin/jvm/internal/DefaultConstructorMarker;)V protected fun getAccessibilityText ()Ljava/lang/String; - public final fun getCachedColorStateList ()Landroid/content/res/ColorStateList; + public final fun getDefaultColorState ()Landroid/content/res/ColorStateList; public final fun getDefaultErrorColorInt ()I public final fun getShouldShowError ()Z protected final fun isLastKeyDelete ()Z @@ -5872,6 +5872,7 @@ public class com/stripe/android/view/StripeEditText : com/google/android/materia public final fun setErrorMessageListener (Lcom/stripe/android/view/StripeEditText$ErrorMessageListener;)V protected final fun setLastKeyDelete (Z)V public final fun setShouldShowError (Z)V + public fun setTextColor (I)V public fun setTextColor (Landroid/content/res/ColorStateList;)V } diff --git a/stripe/src/main/java/com/stripe/android/view/StripeEditText.kt b/stripe/src/main/java/com/stripe/android/view/StripeEditText.kt index f34d06305c8..f50c6d2d284 100644 --- a/stripe/src/main/java/com/stripe/android/view/StripeEditText.kt +++ b/stripe/src/main/java/com/stripe/android/view/StripeEditText.kt @@ -30,8 +30,14 @@ open class StripeEditText @JvmOverloads constructor( private var afterTextChangedListener: AfterTextChangedListener? = null private var deleteEmptyListener: DeleteEmptyListener? = null - var cachedColorStateList: ColorStateList + + var defaultColorState: ColorStateList private set + private var externalColorState: ColorStateList? = null + @ColorInt + private var defaultErrorColor: Int = 0 + @ColorInt + private var externalErrorColor: Int? = null /** * Gets whether or not the text should be displayed in error mode. @@ -48,9 +54,9 @@ open class StripeEditText @JvmOverloads constructor( if (field != shouldShowError) { // only update the view's UI if the property's value is changing if (shouldShowError) { - super.setTextColor(errorColor ?: defaultErrorColor) + super.setTextColor(externalErrorColor ?: defaultErrorColor) } else { - super.setTextColor(cachedColorStateList) + super.setTextColor(externalColorState ?: defaultColorState) } refreshDrawableState() } @@ -65,12 +71,6 @@ open class StripeEditText @JvmOverloads constructor( return text?.toString().orEmpty() } - @ColorInt - private var defaultErrorColor: Int = 0 - - @ColorInt - private var errorColor: Int? = null - private var errorMessageListener: ErrorMessageListener? = null /** @@ -89,7 +89,7 @@ open class StripeEditText @JvmOverloads constructor( maxLines = 1 listenForTextChanges() listenForDeleteEmpty() - cachedColorStateList = textColors + defaultColorState = textColors determineDefaultErrorColor() } @@ -99,14 +99,14 @@ open class StripeEditText @JvmOverloads constructor( super.setTextColor(colors) // This will only use textColors and not colors because textColor is never null - cachedColorStateList = textColors + externalColorState = textColors } override fun setTextColor(color: Int) { super.setTextColor(color) // This will only use textColors and not colors because textColor is never null - cachedColorStateList = ColorStateList.valueOf(color) + externalColorState = ColorStateList.valueOf(color) } override fun onCreateInputConnection(outAttrs: EditorInfo): InputConnection? { @@ -149,7 +149,7 @@ open class StripeEditText @JvmOverloads constructor( * @param errorColor a [ColorInt] */ fun setErrorColor(@ColorInt errorColor: Int) { - this.errorColor = errorColor + this.externalErrorColor = errorColor } override fun onInitializeAccessibilityNodeInfo(info: AccessibilityNodeInfo) { @@ -162,7 +162,7 @@ open class StripeEditText @JvmOverloads constructor( private fun determineDefaultErrorColor() { defaultErrorColor = ContextCompat.getColor( context, - if (StripeColorUtils.isColorDark(cachedColorStateList.defaultColor)) { + if (StripeColorUtils.isColorDark(defaultColorState.defaultColor)) { // Note: if the _text_ color is dark, then this is a // light theme, and vice-versa. R.color.stripe_error_text_light_theme diff --git a/stripe/src/test/java/com/stripe/android/view/StripeEditTextTest.kt b/stripe/src/test/java/com/stripe/android/view/StripeEditTextTest.kt index ef21c9463b2..2a8d89da94c 100644 --- a/stripe/src/test/java/com/stripe/android/view/StripeEditTextTest.kt +++ b/stripe/src/test/java/com/stripe/android/view/StripeEditTextTest.kt @@ -133,7 +133,7 @@ internal class StripeEditTextTest { @Test fun getCachedColorStateList_afterInit_returnsNotNull() { - assertThat(editText.cachedColorStateList) + assertThat(editText.defaultColorState) .isNotNull() } From a9bb03279c4d30fbaabd7c7c451c23e72aeb896d Mon Sep 17 00:00:00 2001 From: Michelle Brubaker Date: Thu, 18 Mar 2021 23:15:01 -0400 Subject: [PATCH 4/6] Fix failing test. --- .../src/main/java/com/stripe/android/view/StripeEditText.kt | 4 +++- .../test/java/com/stripe/android/view/StripeEditTextTest.kt | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/stripe/src/main/java/com/stripe/android/view/StripeEditText.kt b/stripe/src/main/java/com/stripe/android/view/StripeEditText.kt index f50c6d2d284..a9e4b568a6a 100644 --- a/stripe/src/main/java/com/stripe/android/view/StripeEditText.kt +++ b/stripe/src/main/java/com/stripe/android/view/StripeEditText.kt @@ -9,6 +9,7 @@ import android.view.inputmethod.EditorInfo import android.view.inputmethod.InputConnection import android.view.inputmethod.InputConnectionWrapper import androidx.annotation.ColorInt +import androidx.annotation.VisibleForTesting import androidx.core.content.ContextCompat import androidx.core.widget.doAfterTextChanged import com.google.android.material.textfield.TextInputEditText @@ -32,7 +33,8 @@ open class StripeEditText @JvmOverloads constructor( private var deleteEmptyListener: DeleteEmptyListener? = null var defaultColorState: ColorStateList - private set + @VisibleForTesting + internal set private var externalColorState: ColorStateList? = null @ColorInt private var defaultErrorColor: Int = 0 diff --git a/stripe/src/test/java/com/stripe/android/view/StripeEditTextTest.kt b/stripe/src/test/java/com/stripe/android/view/StripeEditTextTest.kt index 2a8d89da94c..aae625082b0 100644 --- a/stripe/src/test/java/com/stripe/android/view/StripeEditTextTest.kt +++ b/stripe/src/test/java/com/stripe/android/view/StripeEditTextTest.kt @@ -82,7 +82,7 @@ internal class StripeEditTextTest { @Test fun getDefaultErrorColorInt_onDarkTheme_returnsDarkError() { - editText.setTextColor(ContextCompat.getColor(context, android.R.color.primary_text_dark)) + editText.defaultColorState = ColorStateList.valueOf(ContextCompat.getColor(context, android.R.color.primary_text_dark)) assertThat(editText.defaultErrorColorInt) .isEqualTo(ContextCompat.getColor(context, R.color.stripe_error_text_dark_theme)) } From 840760ba781906a366461f798881962fa893952e Mon Sep 17 00:00:00 2001 From: Michelle Brubaker Date: Fri, 19 Mar 2021 10:20:49 -0400 Subject: [PATCH 5/6] Minor tweaks for cleanup. --- .../com/stripe/android/view/StripeEditText.kt | 22 +++++++++---------- .../stripe/android/view/StripeEditTextTest.kt | 4 ++-- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/stripe/src/main/java/com/stripe/android/view/StripeEditText.kt b/stripe/src/main/java/com/stripe/android/view/StripeEditText.kt index a9e4b568a6a..c4861947a2c 100644 --- a/stripe/src/main/java/com/stripe/android/view/StripeEditText.kt +++ b/stripe/src/main/java/com/stripe/android/view/StripeEditText.kt @@ -32,10 +32,13 @@ open class StripeEditText @JvmOverloads constructor( private var afterTextChangedListener: AfterTextChangedListener? = null private var deleteEmptyListener: DeleteEmptyListener? = null - var defaultColorState: ColorStateList + internal var defaultColorStateList: ColorStateList @VisibleForTesting internal set - private var externalColorState: ColorStateList? = null + @Deprecated("Will be removed in upcoming major release.") + val cachedColorStateList: ColorStateList + get() = defaultColorStateList + private var externalColorStateList: ColorStateList? = null @ColorInt private var defaultErrorColor: Int = 0 @ColorInt @@ -58,7 +61,7 @@ open class StripeEditText @JvmOverloads constructor( if (shouldShowError) { super.setTextColor(externalErrorColor ?: defaultErrorColor) } else { - super.setTextColor(externalColorState ?: defaultColorState) + super.setTextColor(externalColorStateList ?: defaultColorStateList) } refreshDrawableState() } @@ -91,7 +94,7 @@ open class StripeEditText @JvmOverloads constructor( maxLines = 1 listenForTextChanges() listenForDeleteEmpty() - defaultColorState = textColors + defaultColorStateList = textColors determineDefaultErrorColor() } @@ -101,15 +104,10 @@ open class StripeEditText @JvmOverloads constructor( super.setTextColor(colors) // This will only use textColors and not colors because textColor is never null - externalColorState = textColors + externalColorStateList = textColors } - override fun setTextColor(color: Int) { - super.setTextColor(color) - - // This will only use textColors and not colors because textColor is never null - externalColorState = ColorStateList.valueOf(color) - } + override fun setTextColor(color: Int) = setTextColor(ColorStateList.valueOf(color)) override fun onCreateInputConnection(outAttrs: EditorInfo): InputConnection? { val inputConnection = super.onCreateInputConnection(outAttrs) @@ -164,7 +162,7 @@ open class StripeEditText @JvmOverloads constructor( private fun determineDefaultErrorColor() { defaultErrorColor = ContextCompat.getColor( context, - if (StripeColorUtils.isColorDark(defaultColorState.defaultColor)) { + if (StripeColorUtils.isColorDark(defaultColorStateList.defaultColor)) { // Note: if the _text_ color is dark, then this is a // light theme, and vice-versa. R.color.stripe_error_text_light_theme diff --git a/stripe/src/test/java/com/stripe/android/view/StripeEditTextTest.kt b/stripe/src/test/java/com/stripe/android/view/StripeEditTextTest.kt index aae625082b0..f84019d0523 100644 --- a/stripe/src/test/java/com/stripe/android/view/StripeEditTextTest.kt +++ b/stripe/src/test/java/com/stripe/android/view/StripeEditTextTest.kt @@ -82,7 +82,7 @@ internal class StripeEditTextTest { @Test fun getDefaultErrorColorInt_onDarkTheme_returnsDarkError() { - editText.defaultColorState = ColorStateList.valueOf(ContextCompat.getColor(context, android.R.color.primary_text_dark)) + editText.defaultColorStateList = ColorStateList.valueOf(ContextCompat.getColor(context, android.R.color.primary_text_dark)) assertThat(editText.defaultErrorColorInt) .isEqualTo(ContextCompat.getColor(context, R.color.stripe_error_text_dark_theme)) } @@ -133,7 +133,7 @@ internal class StripeEditTextTest { @Test fun getCachedColorStateList_afterInit_returnsNotNull() { - assertThat(editText.defaultColorState) + assertThat(editText.defaultColorStateList) .isNotNull() } From fe6007ca81be28f8b67c48d3c52e993874511d38 Mon Sep 17 00:00:00 2001 From: Michelle Brubaker Date: Fri, 19 Mar 2021 10:22:54 -0400 Subject: [PATCH 6/6] Minor tweaks for cleanup. --- stripe/api/stripe.api | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stripe/api/stripe.api b/stripe/api/stripe.api index 5e952b00023..a9c6a7d452a 100644 --- a/stripe/api/stripe.api +++ b/stripe/api/stripe.api @@ -5859,7 +5859,7 @@ public class com/stripe/android/view/StripeEditText : com/google/android/materia public fun (Landroid/content/Context;Landroid/util/AttributeSet;I)V public synthetic fun (Landroid/content/Context;Landroid/util/AttributeSet;IILkotlin/jvm/internal/DefaultConstructorMarker;)V protected fun getAccessibilityText ()Ljava/lang/String; - public final fun getDefaultColorState ()Landroid/content/res/ColorStateList; + public final fun getCachedColorStateList ()Landroid/content/res/ColorStateList; public final fun getDefaultErrorColorInt ()I public final fun getShouldShowError ()Z protected final fun isLastKeyDelete ()Z