@@ -219,9 +219,25 @@ public class TextInputLayout extends LinearLayout {
219219
220220 private final IndicatorViewController indicatorViewController = new IndicatorViewController (this );
221221
222+ /** Interface definition for a length counter. */
223+ public interface LengthCounter {
224+
225+ /**
226+ * Counts the length of the text and returns it.
227+ *
228+ * @param text The text to count the length for.
229+ * @return The count that the counter should be updated with.
230+ */
231+ int countLength (@ Nullable Editable text );
232+ }
233+
222234 boolean counterEnabled ;
223235 private int counterMaxLength ;
224236 private boolean counterOverflowed ;
237+
238+ @ NonNull
239+ private LengthCounter lengthCounter = (Editable text ) -> text != null ? text .length () : 0 ;
240+
225241 @ Nullable private TextView counterView ;
226242 private int counterOverflowTextAppearance ;
227243 private int counterTextAppearance ;
@@ -1334,6 +1350,24 @@ public Typeface getTypeface() {
13341350 return typeface ;
13351351 }
13361352
1353+ /**
1354+ * Set the counting method used to count the length of a text.
1355+ *
1356+ * @param lengthCounter the length counter to use.
1357+ */
1358+ public void setLengthCounter (@ NonNull LengthCounter lengthCounter ) {
1359+ this .lengthCounter = lengthCounter ;
1360+ }
1361+
1362+ /**
1363+ * Returns the counting method used to count the length of the text. The default counter will
1364+ * count the number of characters.
1365+ */
1366+ @ NonNull
1367+ public LengthCounter getLengthCounter () {
1368+ return lengthCounter ;
1369+ }
1370+
13371371 @ Override
13381372 @ TargetApi (VERSION_CODES .O )
13391373 public void dispatchProvideAutofillStructure (@ NonNull ViewStructure structure , int flags ) {
@@ -1422,10 +1456,10 @@ private void setEditText(EditText editText) {
14221456 public void afterTextChanged (@ NonNull Editable s ) {
14231457 updateLabelState (!restoringSavedState );
14241458 if (counterEnabled ) {
1425- updateCounter (s . length () );
1459+ updateCounter (s );
14261460 }
14271461 if (placeholderEnabled ) {
1428- updatePlaceholderText (s . length () );
1462+ updatePlaceholderText (s );
14291463 }
14301464 }
14311465
@@ -1454,7 +1488,7 @@ public void onTextChanged(CharSequence s, int start, int before, int count) {}
14541488 }
14551489
14561490 if (counterView != null ) {
1457- updateCounter (this .editText .getText (). length () );
1491+ updateCounter (this .editText .getText ());
14581492 }
14591493 updateEditTextBackground ();
14601494
@@ -2209,11 +2243,13 @@ public void setCounterMaxLength(int maxLength) {
22092243
22102244 private void updateCounter () {
22112245 if (counterView != null ) {
2212- updateCounter (editText == null ? 0 : editText .getText (). length ());
2246+ updateCounter (editText == null ? null : editText .getText ());
22132247 }
22142248 }
22152249
2216- void updateCounter (int length ) {
2250+ void updateCounter (@ Nullable Editable text ) {
2251+ int length = lengthCounter .countLength (text );
2252+
22172253 boolean wasCounterOverflowed = counterOverflowed ;
22182254 if (counterMaxLength == INVALID_MAX_LENGTH ) {
22192255 counterView .setText (String .valueOf (length ));
@@ -2326,11 +2362,12 @@ private Fade createPlaceholderFadeTransition() {
23262362 }
23272363
23282364 private void updatePlaceholderText () {
2329- updatePlaceholderText (editText == null ? 0 : editText .getText (). length ());
2365+ updatePlaceholderText (editText == null ? null : editText .getText ());
23302366 }
23312367
2332- private void updatePlaceholderText (int inputTextLength ) {
2333- if (inputTextLength == 0 && !hintExpanded ) {
2368+ private void updatePlaceholderText (@ Nullable Editable text ) {
2369+ int length = lengthCounter .countLength (text );
2370+ if (length == 0 && !hintExpanded ) {
23342371 showPlaceholderText ();
23352372 } else {
23362373 hidePlaceholderText ();
0 commit comments