diff --git a/api/current.txt b/api/current.txt index 5795575545c3e..2b07a5c54acf0 100644 --- a/api/current.txt +++ b/api/current.txt @@ -49383,6 +49383,10 @@ package android.widget { method public void endBatchEdit(); method public boolean extractText(android.view.inputmethod.ExtractedTextRequest, android.view.inputmethod.ExtractedText); method public final int getAutoLinkMask(); + method public int getAutoSizeMaxTextSize(); + method public int getAutoSizeMinTextSize(); + method public int getAutoSizeStepGranularity(); + method public int getAutoSizeTextType(); method public int getBreakStrategy(); method public int getCompoundDrawablePadding(); method public android.content.res.ColorStateList getCompoundDrawableTintList(); @@ -49491,6 +49495,10 @@ package android.widget { method public void removeTextChangedListener(android.text.TextWatcher); method public void setAllCaps(boolean); method public final void setAutoLinkMask(int); + method public void setAutoSizeMaxTextSize(int, float); + method public void setAutoSizeMinTextSize(int, float); + method public void setAutoSizeStepGranularity(int, float); + method public void setAutoSizeTextType(int); method public void setBreakStrategy(int); method public void setCompoundDrawablePadding(int); method public void setCompoundDrawableTintList(android.content.res.ColorStateList); @@ -49581,8 +49589,8 @@ package android.widget { method public void setTypeface(android.graphics.Typeface, int); method public void setTypeface(android.graphics.Typeface); method public void setWidth(int); - field public static final int AUTO_SIZE_TYPE_NONE = 0; // 0x0 - field public static final int AUTO_SIZE_TYPE_XY = 1; // 0x1 + field public static final int AUTO_SIZE_TEXT_TYPE_NONE = 0; // 0x0 + field public static final int AUTO_SIZE_TEXT_TYPE_XY = 1; // 0x1 } public static final class TextView.BufferType extends java.lang.Enum { diff --git a/api/system-current.txt b/api/system-current.txt index 37fca366450ea..7cb8aaf06be40 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -53018,6 +53018,10 @@ package android.widget { method public void endBatchEdit(); method public boolean extractText(android.view.inputmethod.ExtractedTextRequest, android.view.inputmethod.ExtractedText); method public final int getAutoLinkMask(); + method public int getAutoSizeMaxTextSize(); + method public int getAutoSizeMinTextSize(); + method public int getAutoSizeStepGranularity(); + method public int getAutoSizeTextType(); method public int getBreakStrategy(); method public int getCompoundDrawablePadding(); method public android.content.res.ColorStateList getCompoundDrawableTintList(); @@ -53126,6 +53130,10 @@ package android.widget { method public void removeTextChangedListener(android.text.TextWatcher); method public void setAllCaps(boolean); method public final void setAutoLinkMask(int); + method public void setAutoSizeMaxTextSize(int, float); + method public void setAutoSizeMinTextSize(int, float); + method public void setAutoSizeStepGranularity(int, float); + method public void setAutoSizeTextType(int); method public void setBreakStrategy(int); method public void setCompoundDrawablePadding(int); method public void setCompoundDrawableTintList(android.content.res.ColorStateList); @@ -53216,8 +53224,8 @@ package android.widget { method public void setTypeface(android.graphics.Typeface, int); method public void setTypeface(android.graphics.Typeface); method public void setWidth(int); - field public static final int AUTO_SIZE_TYPE_NONE = 0; // 0x0 - field public static final int AUTO_SIZE_TYPE_XY = 1; // 0x1 + field public static final int AUTO_SIZE_TEXT_TYPE_NONE = 0; // 0x0 + field public static final int AUTO_SIZE_TEXT_TYPE_XY = 1; // 0x1 } public static final class TextView.BufferType extends java.lang.Enum { diff --git a/api/test-current.txt b/api/test-current.txt index 66071a2764bc2..82715b3b4a2e3 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -49688,6 +49688,10 @@ package android.widget { method public void endBatchEdit(); method public boolean extractText(android.view.inputmethod.ExtractedTextRequest, android.view.inputmethod.ExtractedText); method public final int getAutoLinkMask(); + method public int getAutoSizeMaxTextSize(); + method public int getAutoSizeMinTextSize(); + method public int getAutoSizeStepGranularity(); + method public int getAutoSizeTextType(); method public int getBreakStrategy(); method public int getCompoundDrawablePadding(); method public android.content.res.ColorStateList getCompoundDrawableTintList(); @@ -49796,6 +49800,10 @@ package android.widget { method public void removeTextChangedListener(android.text.TextWatcher); method public void setAllCaps(boolean); method public final void setAutoLinkMask(int); + method public void setAutoSizeMaxTextSize(int, float); + method public void setAutoSizeMinTextSize(int, float); + method public void setAutoSizeStepGranularity(int, float); + method public void setAutoSizeTextType(int); method public void setBreakStrategy(int); method public void setCompoundDrawablePadding(int); method public void setCompoundDrawableTintList(android.content.res.ColorStateList); @@ -49886,8 +49894,8 @@ package android.widget { method public void setTypeface(android.graphics.Typeface, int); method public void setTypeface(android.graphics.Typeface); method public void setWidth(int); - field public static final int AUTO_SIZE_TYPE_NONE = 0; // 0x0 - field public static final int AUTO_SIZE_TYPE_XY = 1; // 0x1 + field public static final int AUTO_SIZE_TEXT_TYPE_NONE = 0; // 0x0 + field public static final int AUTO_SIZE_TEXT_TYPE_XY = 1; // 0x1 } public static final class TextView.BufferType extends java.lang.Enum { diff --git a/core/java/android/widget/EditText.java b/core/java/android/widget/EditText.java index af5c8426a44a5..faf0379648973 100644 --- a/core/java/android/widget/EditText.java +++ b/core/java/android/widget/EditText.java @@ -42,6 +42,8 @@ import android.view.autofill.AutoFillValue; *
See the Text Fields * guide.
*+ * This widget does not support auto-sizing text. + *
* XML attributes *
* See {@link android.R.styleable#EditText EditText Attributes}, diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index 08b18a4e53131..b1fc67e56d809 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -22,6 +22,7 @@ import android.R; import android.annotation.ColorInt; import android.annotation.DrawableRes; import android.annotation.FloatRange; +import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.Size; @@ -158,6 +159,8 @@ import com.android.internal.widget.EditableInputConnection; import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Locale; @@ -252,6 +255,10 @@ import java.util.Locale; * @attr ref android.R.styleable#TextView_fontFeatureSettings * @attr ref android.R.styleable#TextView_breakStrategy * @attr ref android.R.styleable#TextView_hyphenationFrequency + * @attr ref android.R.styleable#TextView_autoSizeText + * @attr ref android.R.styleable#TextView_autoSizeMinTextSize + * @attr ref android.R.styleable#TextView_autoSizeMaxTextSize + * @attr ref android.R.styleable#TextView_autoSizeStepGranularity */ @RemoteView public class TextView extends View implements ViewTreeObserver.OnPreDrawListener { @@ -670,17 +677,31 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener */ private int mDeviceProvisionedState = DEVICE_PROVISIONED_UNKNOWN; - // The TextView does not auto-size text. - public static final int AUTO_SIZE_TYPE_NONE = 0; + // The TextView does not auto-size text (default). + public static final int AUTO_SIZE_TEXT_TYPE_NONE = 0; // The TextView performs uniform horizontal and vertical text size scaling to fit within the // container. - public static final int AUTO_SIZE_TYPE_XY = 1; - // Auto-size type. - private int mAutoSizeType = AUTO_SIZE_TYPE_NONE; - // Specify if auto-size is needed. - private boolean mNeedsAutoSize = false; + public static final int AUTO_SIZE_TEXT_TYPE_XY = 1; + /** @hide */ + @IntDef({AUTO_SIZE_TEXT_TYPE_NONE, AUTO_SIZE_TEXT_TYPE_XY}) + @Retention(RetentionPolicy.SOURCE) + public @interface AutoSizeTextType {} + // Default minimum size for auto-sizing text in scaled pixels. {@see #setAutoSizeMinTextSize}. + private static final int DEFAULT_AUTO_SIZE_MIN_TEXT_SIZE_IN_SP = 12; + // Default maximum size for auto-sizing text in scaled pixels. {@see #setAutoSizeMaxTextSize}. + private static final int DEFAULT_AUTO_SIZE_MAX_TEXT_SIZE_IN_SP = 112; // Default value for the step size in pixels. private static final int DEFAULT_AUTO_SIZE_GRANULARITY_IN_PX = 1; + // Auto-size text type. + private int mAutoSizeTextType = AUTO_SIZE_TEXT_TYPE_NONE; + // Specify if auto-size text is needed. + private boolean mNeedsAutoSizeText = false; + // Step size for auto-sizing in pixels. + private int mAutoSizeStepGranularityInPx = 0; + // Minimum text size for auto-sizing in pixels. + private int mAutoSizeMinTextSizeInPx = 0; + // Maximum text size for auto-sizing in pixels. + private int mAutoSizeMaxTextSizeInPx = 0; // Contains the sorted set of desired text sizes in pixels to pick from when auto-sizing text. private int[] mAutoSizeTextSizesInPx; @@ -887,13 +908,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener CharSequence hint = null; boolean password = false; int inputType = EditorInfo.TYPE_NULL; - int autoSizeStepGranularityInPx = DEFAULT_AUTO_SIZE_GRANULARITY_IN_PX; - int autoSizeMinTextSize = (int) TypedValue.applyDimension( - TypedValue.COMPLEX_UNIT_SP, 12, getResources().getDisplayMetrics()); - int autoSizeMaxTextSize = (int) TypedValue.applyDimension( - TypedValue.COMPLEX_UNIT_SP, 112, getResources().getDisplayMetrics()); - - a = theme.obtainStyledAttributes( attrs, com.android.internal.R.styleable.TextView, defStyleAttr, defStyleRes); @@ -1249,20 +1263,19 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener break; case com.android.internal.R.styleable.TextView_autoSizeText: - mAutoSizeType = a.getInt(attr, AUTO_SIZE_TYPE_NONE); + mAutoSizeTextType = a.getInt(attr, AUTO_SIZE_TEXT_TYPE_NONE); break; case com.android.internal.R.styleable.TextView_autoSizeStepGranularity: - autoSizeStepGranularityInPx = a.getDimensionPixelSize( - attr, DEFAULT_AUTO_SIZE_GRANULARITY_IN_PX); + mAutoSizeStepGranularityInPx = a.getDimensionPixelSize(attr, 0); break; case com.android.internal.R.styleable.TextView_autoSizeMinTextSize: - autoSizeMinTextSize = a.getDimensionPixelSize(attr, autoSizeMinTextSize); + mAutoSizeMinTextSizeInPx = a.getDimensionPixelSize(attr, 0); break; case com.android.internal.R.styleable.TextView_autoSizeMaxTextSize: - autoSizeMaxTextSize = a.getDimensionPixelSize(attr, autoSizeMaxTextSize); + mAutoSizeMaxTextSizeInPx = a.getDimensionPixelSize(attr, 0); break; } } @@ -1542,39 +1555,204 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES); } - // Setup auto-size. + setupAutoSizeTextXY(); + } + + /** + * Specify whether this widget should automatically scale the text to try to perfectly fit + * within the layout bounds by taking into account the auto-size configuration. + * + * @param autoSizeTextType the type of auto-size. Must be one of + * {@link TextView#AUTO_SIZE_TEXT_TYPE_NONE} or + * {@link TextView#AUTO_SIZE_TEXT_TYPE_XY} + * + * @attr ref android.R.styleable#TextView_autoSizeText + * + * @see #getAutoSizeTextType() + */ + public void setAutoSizeTextType(@AutoSizeTextType int autoSizeTextType) { if (supportsAutoSizeText()) { - switch (mAutoSizeType) { - case AUTO_SIZE_TYPE_NONE: - // Nothing to do. + switch (autoSizeTextType) { + case AUTO_SIZE_TEXT_TYPE_NONE: + if (mAutoSizeTextType != AUTO_SIZE_TEXT_TYPE_NONE) { + // Clear all auto-size configuration + mAutoSizeTextType = AUTO_SIZE_TEXT_TYPE_NONE; + mAutoSizeMinTextSizeInPx = 0; + mAutoSizeMaxTextSizeInPx = 0; + mAutoSizeStepGranularityInPx = 0; + mAutoSizeTextSizesInPx = null; + mNeedsAutoSizeText = false; + } break; - case AUTO_SIZE_TYPE_XY: - if (autoSizeMaxTextSize <= autoSizeMinTextSize) { - throw new IllegalStateException("Maximum text size is less then minimum " - + "text size"); + case AUTO_SIZE_TEXT_TYPE_XY: + if (mAutoSizeTextType != AUTO_SIZE_TEXT_TYPE_XY) { + mAutoSizeTextType = AUTO_SIZE_TEXT_TYPE_XY; + setupAutoSizeTextXY(); } - - if (autoSizeStepGranularityInPx <= 0) { - throw new IllegalStateException("Unexpected zero or negative value for auto" - + " size step granularity in pixels"); - } - - final int autoSizeValuesLength = (autoSizeMaxTextSize - autoSizeMinTextSize) - / autoSizeStepGranularityInPx; - mAutoSizeTextSizesInPx = new int[autoSizeValuesLength]; - int sizeToAdd = autoSizeMinTextSize; - for (int i = 0; i < autoSizeValuesLength; i++) { - mAutoSizeTextSizesInPx[i] = sizeToAdd; - sizeToAdd += autoSizeStepGranularityInPx; - } - - mNeedsAutoSize = true; break; default: throw new IllegalArgumentException( - "Unknown autoSizeText type: " + mAutoSizeType); + "Unknown auto-size text type: " + autoSizeTextType); + } + } + } + + /** + * Returns the type of auto-size set for this widget. + * + * @return an {@code int} corresponding to one of the auto-size types: + * {@link TextView#AUTO_SIZE_TEXT_TYPE_NONE} or + * {@link TextView#AUTO_SIZE_TEXT_TYPE_XY} + * + * @attr ref android.R.styleable#TextView_autoSizeText + * + * @see #setAutoSizeTextType(int) + */ + @AutoSizeTextType + public int getAutoSizeTextType() { + return mAutoSizeTextType; + } + + /** + * Sets the auto-size step granularity. It is used in conjunction with auto-size minimum + * and maximum text size in order to build the set of text sizes the system uses to choose + * from when auto-sizing. + * + * @param unit the desired dimension unit. See {@link TypedValue} for the possible + * dimension units + * @param size the desired size in the given units + * + * @attr ref android.R.styleable#TextView_autoSizeStepGranularity + * + * @see #getAutoSizeStepGranularity() + * @see #setAutoSizeMinTextSize(int, float) + * @see #setAutoSizeMaxTextSize(int, float) + */ + public void setAutoSizeStepGranularity(int unit, float size) { + if (supportsAutoSizeText()) { + mAutoSizeStepGranularityInPx = (int) TypedValue.applyDimension( + unit, size, getResources().getDisplayMetrics()); + setupAutoSizeTextXY(); + } + } + + /** + * @return the current auto-size step granularity in pixels. + * + * @see #setAutoSizeStepGranularity(int, float) + */ + public int getAutoSizeStepGranularity() { + return mAutoSizeStepGranularityInPx; + } + + /** + * Sets the minimum text size to be used in conjunction with auto-size maximum text size and + * auto-size step granularity in order to build the set of text sizes the system uses to choose + * from when auto-sizing. + * + * @param unit the desired dimension unit. See {@link TypedValue} for the possible + * dimension units + * @param size the desired size in the given units + * + * @attr ref android.R.styleable#TextView_autoSizeMinTextSize + * + * @see #getAutoSizeMinTextSize() + * @see #setAutoSizeMaxTextSize(int, float) + * @see #setAutoSizeStepGranularity(int, float) + */ + public void setAutoSizeMinTextSize(int unit, float size) { + if (supportsAutoSizeText()) { + mAutoSizeMinTextSizeInPx = (int) TypedValue.applyDimension( + unit, size, getResources().getDisplayMetrics()); + setupAutoSizeTextXY(); + } + } + + /** + * @return the current auto-size minimum text size in pixels (the default is 12sp). Note that + * if auto-size has not been configured this function returns {@code 0}. + * + * @see #setAutoSizeMinTextSize(int, float) + */ + public int getAutoSizeMinTextSize() { + return mAutoSizeMinTextSizeInPx; + } + + /** + * Sets the maximum text size to be used in conjunction with auto-size minimum text size and + * auto-size step granularity in order to build the set of text sizes the system uses to choose + * from when auto-sizing. + * + * @param unit the desired dimension unit. See {@link TypedValue} for the possible + * dimension units + * @param size the desired size in the given units + * + * @attr ref android.R.styleable#TextView_autoSizeMaxTextSize + * + * @see #getAutoSizeMaxTextSize() + * @see #setAutoSizeMinTextSize(int, float) + * @see #setAutoSizeStepGranularity(int, float) + */ + public void setAutoSizeMaxTextSize(int unit, float size) { + if (supportsAutoSizeText()) { + mAutoSizeMaxTextSizeInPx = (int) TypedValue.applyDimension( + unit, size, getResources().getDisplayMetrics()); + setupAutoSizeTextXY(); + } + } + + /** + * @return the current auto-size maximum text size in pixels (the default is 112sp). Note that + * if auto-size has not been configured this function returns {@code 0}. + * + * @see #setAutoSizeMaxTextSize(int, float) + */ + public int getAutoSizeMaxTextSize() { + return mAutoSizeMaxTextSizeInPx; + } + + private void setupAutoSizeTextXY() { + if (supportsAutoSizeText() && mAutoSizeTextType == AUTO_SIZE_TEXT_TYPE_XY) { + // Set valid defaults. + if (mAutoSizeMinTextSizeInPx <= 0) { + mAutoSizeMinTextSizeInPx = (int) TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_SP, + DEFAULT_AUTO_SIZE_MIN_TEXT_SIZE_IN_SP, + getResources().getDisplayMetrics()); } + if (mAutoSizeMaxTextSizeInPx <= 0) { + mAutoSizeMaxTextSizeInPx = (int) TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_SP, + DEFAULT_AUTO_SIZE_MAX_TEXT_SIZE_IN_SP, + getResources().getDisplayMetrics()); + } + + if (mAutoSizeStepGranularityInPx <= 0) { + mAutoSizeStepGranularityInPx = DEFAULT_AUTO_SIZE_GRANULARITY_IN_PX; + } + + // Validate. + if (mAutoSizeMaxTextSizeInPx <= mAutoSizeMinTextSizeInPx) { + throw new IllegalStateException("Maximum auto-size text size (" + + mAutoSizeMaxTextSizeInPx + "px) is less or equal to minimum auto-size " + + "text size (" + mAutoSizeMinTextSizeInPx + "px)"); + } + + // Calculate sizes to choose from based on the current auto-size configuration. + final int autoSizeValuesLength = (int) Math.ceil( + (mAutoSizeMaxTextSizeInPx - mAutoSizeMinTextSizeInPx) + / mAutoSizeStepGranularityInPx); + + mAutoSizeTextSizesInPx = new int[autoSizeValuesLength]; + int sizeToAdd = mAutoSizeMinTextSizeInPx; + for (int i = 0; i < autoSizeValuesLength; i++) { + mAutoSizeTextSizesInPx[i] = sizeToAdd; + sizeToAdd += mAutoSizeStepGranularityInPx; + } + + mNeedsAutoSizeText = true; + autoSizeText(); } } @@ -3030,9 +3208,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener /** * @return the size (in pixels) of the default text size in this TextView. - * - *
Note: if this TextView has mAutoSizeType set to {@link TextView#AUTO_SIZE_TYPE_XY} than - * this function returns the maximum text size for auto-sizing. */ @ViewDebug.ExportedProperty(category = "text") public float getTextSize() { @@ -3077,7 +3252,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } /** - * Set the default text size to a given unit and value. See {@link + * Set the default text size to a given unit and value. See {@link * TypedValue} for the possible dimension units. * *
Note: if this TextView has the auto-size feature enabled than this function is no-op.
@@ -3113,7 +3288,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
if (mLayout != null) {
// Do not auto-size right after setting the text size.
- mNeedsAutoSize = false;
+ mNeedsAutoSizeText = false;
nullLayouts();
requestLayout();
invalidate();
@@ -7563,13 +7738,13 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
if (isAutoSizeEnabled()) {
- if (mNeedsAutoSize) {
+ if (mNeedsAutoSizeText) {
// Call auto-size after the width and height have been calculated.
autoSizeText();
}
// Always try to auto-size if enabled. Functions that do not want to trigger auto-sizing
// after the next measuring round should set this to false.
- mNeedsAutoSize = true;
+ mNeedsAutoSizeText = true;
}
setMeasuredDimension(width, height);
@@ -9328,7 +9503,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
* auto-size.
*/
private boolean isAutoSizeEnabled() {
- return supportsAutoSizeText() && mAutoSizeType != AUTO_SIZE_TYPE_NONE;
+ return supportsAutoSizeText() && mAutoSizeTextType != AUTO_SIZE_TEXT_TYPE_NONE;
}
/**
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index a40131469076d..7c01dea63cee8 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -4707,7 +4707,8 @@
screens with limited space for text. -->