Skip to content

Commit

Permalink
New option: minCharacters
Browse files Browse the repository at this point in the history
  • Loading branch information
rengwuxian committed Dec 12, 2014
1 parent 42d9a31 commit ea0f255
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,12 @@ public class MaterialAutoCompleteTextView extends AutoCompleteTextView {
private int errorColor;

/**
* characters count limit. 0 means no limit. default is 0. NOTE: the character counter will increase the View's height.
* min characters count limit. 0 means no limit. default is 0. NOTE: the character counter will increase the View's height.
*/
private int minCharacters;

/**
* max characters count limit. 0 means no limit. default is 0. NOTE: the character counter will increase the View's height.
*/
private int maxCharacters;

Expand Down Expand Up @@ -260,6 +265,7 @@ public MaterialAutoCompleteTextView(Context context, AttributeSet attrs, int sty
primaryColor = typedArray.getColor(R.styleable.MaterialEditText_primaryColor, defaultPrimaryColor);
setFloatingLabelInternal(typedArray.getInt(R.styleable.MaterialEditText_floatingLabel, 0));
errorColor = typedArray.getColor(R.styleable.MaterialEditText_errorColor, Color.parseColor("#e7492E"));
minCharacters = typedArray.getInt(R.styleable.MaterialEditText_minCharacters, 0);
maxCharacters = typedArray.getInt(R.styleable.MaterialEditText_maxCharacters, 0);
singleLineEllipsis = typedArray.getBoolean(R.styleable.MaterialEditText_singleLineEllipsis, false);
helperText = typedArray.getString(R.styleable.MaterialEditText_helperText);
Expand Down Expand Up @@ -421,7 +427,7 @@ private void initPadding() {
* calculate {@link #minBottomLines}
*/
private void initMinBottomLines() {
boolean extendBottom = maxCharacters > 0 || singleLineEllipsis || tempErrorText != null || helperText != null;
boolean extendBottom = minCharacters > 0 || maxCharacters > 0 || singleLineEllipsis || tempErrorText != null || helperText != null;
currentBottomLines = minBottomLines = minBottomTextLines > 0 ? minBottomTextLines : extendBottom ? 1 : 0;
}

Expand Down Expand Up @@ -603,6 +609,17 @@ public void setMaxCharacters(int max) {
postInvalidate();
}

public int getMinCharacters() {
return minCharacters;
}

public void setMinCharacters(int min) {
minCharacters = min;
initMinBottomLines();
initPadding();
postInvalidate();
}

public int getErrorColor() {
return errorColor;
}
Expand Down Expand Up @@ -647,7 +664,7 @@ public CharSequence getError() {
* only used to draw the bottom line
*/
private boolean isInternalValid() {
return tempErrorText == null && isMaxCharactersValid();
return tempErrorText == null && isCharactersCountValid();
}

/**
Expand Down Expand Up @@ -811,9 +828,17 @@ protected void onDraw(@NonNull Canvas canvas) {
float fontPaddingTop = floatingLabelTextSize + fontMetrics.ascent + fontMetrics.descent;

// draw the characters counter
if ((hasFocus() && maxCharacters > 0) || !isMaxCharactersValid()) {
textPaint.setColor(isMaxCharactersValid() ? getCurrentHintTextColor() : errorColor);
String text = getText().length() + " / " + maxCharacters;
if ((hasFocus() && hasCharatersCounter()) || !isCharactersCountValid()) {
textPaint.setColor(isCharactersCountValid() ? getCurrentHintTextColor() : errorColor);
String text;
if (minCharacters <= 0) {
text = getText().length() + " / " + maxCharacters;
} else if (maxCharacters <= 0) {
text = getText().length() + " / " + minCharacters + "+";
} else {
text = getText().length() + " / " + minCharacters + "-" + maxCharacters;
}

canvas.drawText(text, getWidth() + getScrollX() - textPaint.measureText(text), lineStartY + bottomSpacing + relativeHeight, textPaint);
}

Expand Down Expand Up @@ -871,11 +896,15 @@ private int getBottomTextLeftOffset() {
}

private int getBottomTextRightOffset() {
return maxCharacters > 0 ? (int) textPaint.measureText("00/000") : 0;
return hasCharatersCounter() ? (int) textPaint.measureText("00/000") : 0;
}

public boolean isCharactersCountValid() {
return !hasCharatersCounter() || getText() == null || getText().length() == 0 || (getText().length() >= minCharacters && (maxCharacters <= 0 || getText().length() <= maxCharacters));
}

public boolean isMaxCharactersValid() {
return maxCharacters <= 0 || getText() == null || getText().length() <= maxCharacters;
private boolean hasCharatersCounter() {
return minCharacters > 0 || maxCharacters > 0;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,12 @@ public class MaterialEditText extends EditText {
private int errorColor;

/**
* characters count limit. 0 means no limit. default is 0. NOTE: the character counter will increase the View's height.
* min characters count limit. 0 means no limit. default is 0. NOTE: the character counter will increase the View's height.
*/
private int minCharacters;

/**
* max characters count limit. 0 means no limit. default is 0. NOTE: the character counter will increase the View's height.
*/
private int maxCharacters;

Expand Down Expand Up @@ -260,6 +265,7 @@ public MaterialEditText(Context context, AttributeSet attrs, int style) {
primaryColor = typedArray.getColor(R.styleable.MaterialEditText_primaryColor, defaultPrimaryColor);
setFloatingLabelInternal(typedArray.getInt(R.styleable.MaterialEditText_floatingLabel, 0));
errorColor = typedArray.getColor(R.styleable.MaterialEditText_errorColor, Color.parseColor("#e7492E"));
minCharacters = typedArray.getInt(R.styleable.MaterialEditText_minCharacters, 0);
maxCharacters = typedArray.getInt(R.styleable.MaterialEditText_maxCharacters, 0);
singleLineEllipsis = typedArray.getBoolean(R.styleable.MaterialEditText_singleLineEllipsis, false);
helperText = typedArray.getString(R.styleable.MaterialEditText_helperText);
Expand Down Expand Up @@ -421,7 +427,7 @@ private void initPadding() {
* calculate {@link #minBottomLines}
*/
private void initMinBottomLines() {
boolean extendBottom = maxCharacters > 0 || singleLineEllipsis || tempErrorText != null || helperText != null;
boolean extendBottom = minCharacters > 0 || maxCharacters > 0 || singleLineEllipsis || tempErrorText != null || helperText != null;
currentBottomLines = minBottomLines = minBottomTextLines > 0 ? minBottomTextLines : extendBottom ? 1 : 0;
}

Expand Down Expand Up @@ -603,6 +609,17 @@ public void setMaxCharacters(int max) {
postInvalidate();
}

public int getMinCharacters() {
return minCharacters;
}

public void setMinCharacters(int min) {
minCharacters = min;
initMinBottomLines();
initPadding();
postInvalidate();
}

public int getErrorColor() {
return errorColor;
}
Expand Down Expand Up @@ -647,7 +664,7 @@ public CharSequence getError() {
* only used to draw the bottom line
*/
private boolean isInternalValid() {
return tempErrorText == null && isMaxCharactersValid();
return tempErrorText == null && isCharactersCountValid();
}

/**
Expand Down Expand Up @@ -811,9 +828,17 @@ protected void onDraw(@NonNull Canvas canvas) {
float fontPaddingTop = floatingLabelTextSize + fontMetrics.ascent + fontMetrics.descent;

// draw the characters counter
if ((hasFocus() && maxCharacters > 0) || !isMaxCharactersValid()) {
textPaint.setColor(isMaxCharactersValid() ? getCurrentHintTextColor() : errorColor);
String text = getText().length() + " / " + maxCharacters;
if ((hasFocus() && hasCharatersCounter()) || !isCharactersCountValid()) {
textPaint.setColor(isCharactersCountValid() ? getCurrentHintTextColor() : errorColor);
String text;
if (minCharacters <= 0) {
text = getText().length() + " / " + maxCharacters;
} else if (maxCharacters <= 0) {
text = getText().length() + " / " + minCharacters + "+";
} else {
text = getText().length() + " / " + minCharacters + "-" + maxCharacters;
}

canvas.drawText(text, getWidth() + getScrollX() - textPaint.measureText(text), lineStartY + bottomSpacing + relativeHeight, textPaint);
}

Expand Down Expand Up @@ -871,11 +896,15 @@ private int getBottomTextLeftOffset() {
}

private int getBottomTextRightOffset() {
return maxCharacters > 0 ? (int) textPaint.measureText("00/000") : 0;
return hasCharatersCounter() ? (int) textPaint.measureText("00/000") : 0;
}

public boolean isCharactersCountValid() {
return !hasCharatersCounter() || getText() == null || getText().length() == 0 || (getText().length() >= minCharacters && (maxCharacters <= 0 || getText().length() <= maxCharacters));
}

public boolean isMaxCharactersValid() {
return maxCharacters <= 0 || getText() == null || getText().length() <= maxCharacters;
private boolean hasCharatersCounter() {
return minCharacters > 0 || maxCharacters > 0;
}

@Override
Expand Down
4 changes: 3 additions & 1 deletion library/src/main/res/values/attrs.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@
</attr>
<!-- The color for when something is wrong.(e.g. exceeding max characters) -->
<attr name="errorColor" format="color"/>
<!-- Characters count limit. 0 means no limit. -->
<!-- Min characters count limit. 0 means no limit. -->
<attr name="minCharacters" format="integer"/>
<!-- max Characters count limit. 0 means no limit. -->
<attr name="maxCharacters" format="integer"/>
<!-- Whether to show the bottom ellipsis in singleLine mode -->
<attr name="singleLineEllipsis" format="boolean"/>
Expand Down
2 changes: 1 addition & 1 deletion sample/src/main/res/layout/activity_main.xml
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Max Characters"
app:maxCharacters="10"/>
app:minCharacters="8"/>

<TextView
android:layout_width="match_parent"
Expand Down

0 comments on commit ea0f255

Please sign in to comment.