Apply max char length when setSingleLine is called.
Bug: 145128646 Test: atest android.widget.cts.EditTextTest Change-Id: I1f2fd6c97c5cdeb7be5017d4c6aeb19fd269e939
This commit is contained in:
@@ -398,6 +398,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
|||||||
|
|
||||||
// Maximum text length for single line input.
|
// Maximum text length for single line input.
|
||||||
private static final int MAX_LENGTH_FOR_SINGLE_LINE_EDIT_TEXT = 5000;
|
private static final int MAX_LENGTH_FOR_SINGLE_LINE_EDIT_TEXT = 5000;
|
||||||
|
private InputFilter.LengthFilter mSingleLineLengthFilter = null;
|
||||||
|
|
||||||
private static final RectF TEMP_RECTF = new RectF();
|
private static final RectF TEMP_RECTF = new RectF();
|
||||||
|
|
||||||
@@ -1602,7 +1603,11 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
|||||||
// Same as setSingleLine(), but make sure the transformation method and the maximum number
|
// Same as setSingleLine(), but make sure the transformation method and the maximum number
|
||||||
// of lines of height are unchanged for multi-line TextViews.
|
// of lines of height are unchanged for multi-line TextViews.
|
||||||
setInputTypeSingleLine(singleLine);
|
setInputTypeSingleLine(singleLine);
|
||||||
applySingleLine(singleLine, singleLine, singleLine);
|
applySingleLine(singleLine, singleLine, singleLine,
|
||||||
|
// Does not apply automated max length filter since length filter will be resolved
|
||||||
|
// later in this function.
|
||||||
|
false
|
||||||
|
);
|
||||||
|
|
||||||
if (singleLine && getKeyListener() == null && ellipsize == ELLIPSIZE_NOT_SET) {
|
if (singleLine && getKeyListener() == null && ellipsize == ELLIPSIZE_NOT_SET) {
|
||||||
ellipsize = ELLIPSIZE_END;
|
ellipsize = ELLIPSIZE_END;
|
||||||
@@ -1649,10 +1654,13 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
|||||||
// For addressing b/145128646
|
// For addressing b/145128646
|
||||||
// For the performance reason, we limit characters for single line text field.
|
// For the performance reason, we limit characters for single line text field.
|
||||||
if (bufferType == BufferType.EDITABLE && singleLine && maxlength == -1) {
|
if (bufferType == BufferType.EDITABLE && singleLine && maxlength == -1) {
|
||||||
maxlength = MAX_LENGTH_FOR_SINGLE_LINE_EDIT_TEXT;
|
mSingleLineLengthFilter = new InputFilter.LengthFilter(
|
||||||
|
MAX_LENGTH_FOR_SINGLE_LINE_EDIT_TEXT);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (maxlength >= 0) {
|
if (mSingleLineLengthFilter != null) {
|
||||||
|
setFilters(new InputFilter[] { mSingleLineLengthFilter });
|
||||||
|
} else if (maxlength >= 0) {
|
||||||
setFilters(new InputFilter[] { new InputFilter.LengthFilter(maxlength) });
|
setFilters(new InputFilter[] { new InputFilter.LengthFilter(maxlength) });
|
||||||
} else {
|
} else {
|
||||||
setFilters(NO_FILTERS);
|
setFilters(NO_FILTERS);
|
||||||
@@ -6610,7 +6618,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
|||||||
if (mSingleLine != singleLine || forceUpdate) {
|
if (mSingleLine != singleLine || forceUpdate) {
|
||||||
// Change single line mode, but only change the transformation if
|
// Change single line mode, but only change the transformation if
|
||||||
// we are not in password mode.
|
// we are not in password mode.
|
||||||
applySingleLine(singleLine, !isPassword, true);
|
applySingleLine(singleLine, !isPassword, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isSuggestionsEnabled()) {
|
if (!isSuggestionsEnabled()) {
|
||||||
@@ -10254,6 +10262,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
|||||||
* Note that the default conditions are not necessarily those that were in effect prior this
|
* Note that the default conditions are not necessarily those that were in effect prior this
|
||||||
* method, and you may want to reset these properties to your custom values.
|
* method, and you may want to reset these properties to your custom values.
|
||||||
*
|
*
|
||||||
|
* Note that due to performance reasons, by setting single line for the EditText, the maximum
|
||||||
|
* text length is set to 5000 if no other character limitation are applied.
|
||||||
|
*
|
||||||
* @attr ref android.R.styleable#TextView_singleLine
|
* @attr ref android.R.styleable#TextView_singleLine
|
||||||
*/
|
*/
|
||||||
@android.view.RemotableViewMethod
|
@android.view.RemotableViewMethod
|
||||||
@@ -10261,7 +10272,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
|||||||
// Could be used, but may break backward compatibility.
|
// Could be used, but may break backward compatibility.
|
||||||
// if (mSingleLine == singleLine) return;
|
// if (mSingleLine == singleLine) return;
|
||||||
setInputTypeSingleLine(singleLine);
|
setInputTypeSingleLine(singleLine);
|
||||||
applySingleLine(singleLine, true, true);
|
applySingleLine(singleLine, true, true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -10281,14 +10292,40 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void applySingleLine(boolean singleLine, boolean applyTransformation,
|
private void applySingleLine(boolean singleLine, boolean applyTransformation,
|
||||||
boolean changeMaxLines) {
|
boolean changeMaxLines, boolean changeMaxLength) {
|
||||||
mSingleLine = singleLine;
|
mSingleLine = singleLine;
|
||||||
|
|
||||||
if (singleLine) {
|
if (singleLine) {
|
||||||
setLines(1);
|
setLines(1);
|
||||||
setHorizontallyScrolling(true);
|
setHorizontallyScrolling(true);
|
||||||
if (applyTransformation) {
|
if (applyTransformation) {
|
||||||
setTransformationMethod(SingleLineTransformationMethod.getInstance());
|
setTransformationMethod(SingleLineTransformationMethod.getInstance());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!changeMaxLength) return;
|
||||||
|
|
||||||
|
// Single line length filter is only applicable editable text.
|
||||||
|
if (mBufferType != BufferType.EDITABLE) return;
|
||||||
|
|
||||||
|
final InputFilter[] prevFilters = getFilters();
|
||||||
|
for (InputFilter filter: getFilters()) {
|
||||||
|
// We don't add LengthFilter if already there.
|
||||||
|
if (filter instanceof InputFilter.LengthFilter) return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mSingleLineLengthFilter == null) {
|
||||||
|
mSingleLineLengthFilter = new InputFilter.LengthFilter(
|
||||||
|
MAX_LENGTH_FOR_SINGLE_LINE_EDIT_TEXT);
|
||||||
|
}
|
||||||
|
|
||||||
|
final InputFilter[] newFilters = new InputFilter[prevFilters.length + 1];
|
||||||
|
System.arraycopy(prevFilters, 0, newFilters, 0, prevFilters.length);
|
||||||
|
newFilters[prevFilters.length] = mSingleLineLengthFilter;
|
||||||
|
|
||||||
|
setFilters(newFilters);
|
||||||
|
|
||||||
|
// Since filter doesn't apply to existing text, trigger filter by setting text.
|
||||||
|
setText(getText());
|
||||||
} else {
|
} else {
|
||||||
if (changeMaxLines) {
|
if (changeMaxLines) {
|
||||||
setMaxLines(Integer.MAX_VALUE);
|
setMaxLines(Integer.MAX_VALUE);
|
||||||
@@ -10297,6 +10334,47 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
|||||||
if (applyTransformation) {
|
if (applyTransformation) {
|
||||||
setTransformationMethod(null);
|
setTransformationMethod(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!changeMaxLength) return;
|
||||||
|
|
||||||
|
// Single line length filter is only applicable editable text.
|
||||||
|
if (mBufferType != BufferType.EDITABLE) return;
|
||||||
|
|
||||||
|
final InputFilter[] prevFilters = getFilters();
|
||||||
|
if (prevFilters.length == 0) return;
|
||||||
|
|
||||||
|
// Short Circuit: if mSingleLineLengthFilter is not allocated, nobody sets automated
|
||||||
|
// single line char limit filter.
|
||||||
|
if (mSingleLineLengthFilter == null) return;
|
||||||
|
|
||||||
|
// If we need to remove mSingleLineLengthFilter, we need to allocate another array.
|
||||||
|
// Since filter list is expected to be small and want to avoid unnecessary array
|
||||||
|
// allocation, check if there is mSingleLengthFilter first.
|
||||||
|
int targetIndex = -1;
|
||||||
|
for (int i = 0; i < prevFilters.length; ++i) {
|
||||||
|
if (prevFilters[i] == mSingleLineLengthFilter) {
|
||||||
|
targetIndex = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (targetIndex == -1) return; // not found. Do nothing.
|
||||||
|
|
||||||
|
if (prevFilters.length == 1) {
|
||||||
|
setFilters(NO_FILTERS);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create new array which doesn't include mSingleLengthFilter.
|
||||||
|
final InputFilter[] newFilters = new InputFilter[prevFilters.length - 1];
|
||||||
|
System.arraycopy(prevFilters, 0, newFilters, 0, targetIndex);
|
||||||
|
System.arraycopy(
|
||||||
|
prevFilters,
|
||||||
|
targetIndex + 1,
|
||||||
|
newFilters,
|
||||||
|
targetIndex,
|
||||||
|
prevFilters.length - targetIndex - 1);
|
||||||
|
setFilters(newFilters);
|
||||||
|
mSingleLineLengthFilter = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user