diff options
author | 2017-02-08 14:57:39 +0000 | |
---|---|---|
committer | 2017-02-08 14:57:43 +0000 | |
commit | f9a55d42d2e2adbf5895d04e4790debb145508ed (patch) | |
tree | 64de1d1f015b9afc1b9f4017750e22f502d86314 | |
parent | 24843fdf3b24c0cd0d7c8f7b0921072f115a66f1 (diff) | |
parent | 9fe208fe6b0c0aef797a2d3757f50b88ecd86a0c (diff) |
Merge "AutoSize TextView (part 8) - APIs for predefined sizes"
-rw-r--r-- | api/current.txt | 2 | ||||
-rw-r--r-- | api/system-current.txt | 2 | ||||
-rw-r--r-- | api/test-current.txt | 2 | ||||
-rw-r--r-- | core/java/android/widget/TextView.java | 211 |
4 files changed, 167 insertions, 50 deletions
diff --git a/api/current.txt b/api/current.txt index 5c1bff80b655..f2d7e2155a05 100644 --- a/api/current.txt +++ b/api/current.txt @@ -50369,6 +50369,7 @@ package android.widget { method public int getAutoSizeMaxTextSize(); method public int getAutoSizeMinTextSize(); method public int getAutoSizeStepGranularity(); + method public int[] getAutoSizeTextPresetSizes(); method public int getAutoSizeTextType(); method public int getBreakStrategy(); method public int getCompoundDrawablePadding(); @@ -50482,6 +50483,7 @@ package android.widget { method public void setAutoSizeMaxTextSize(int, float); method public void setAutoSizeMinTextSize(int, float); method public void setAutoSizeStepGranularity(int, float); + method public void setAutoSizeTextPresetSizes(int[]); method public void setAutoSizeTextType(int); method public void setBreakStrategy(int); method public void setCompoundDrawablePadding(int); diff --git a/api/system-current.txt b/api/system-current.txt index a29c7f8a71e4..760ba13785be 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -54149,6 +54149,7 @@ package android.widget { method public int getAutoSizeMaxTextSize(); method public int getAutoSizeMinTextSize(); method public int getAutoSizeStepGranularity(); + method public int[] getAutoSizeTextPresetSizes(); method public int getAutoSizeTextType(); method public int getBreakStrategy(); method public int getCompoundDrawablePadding(); @@ -54262,6 +54263,7 @@ package android.widget { method public void setAutoSizeMaxTextSize(int, float); method public void setAutoSizeMinTextSize(int, float); method public void setAutoSizeStepGranularity(int, float); + method public void setAutoSizeTextPresetSizes(int[]); method public void setAutoSizeTextType(int); method public void setBreakStrategy(int); method public void setCompoundDrawablePadding(int); diff --git a/api/test-current.txt b/api/test-current.txt index 5d6f5d08646d..df2e7cea6963 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -50689,6 +50689,7 @@ package android.widget { method public int getAutoSizeMaxTextSize(); method public int getAutoSizeMinTextSize(); method public int getAutoSizeStepGranularity(); + method public int[] getAutoSizeTextPresetSizes(); method public int getAutoSizeTextType(); method public int getBreakStrategy(); method public int getCompoundDrawablePadding(); @@ -50802,6 +50803,7 @@ package android.widget { method public void setAutoSizeMaxTextSize(int, float); method public void setAutoSizeMinTextSize(int, float); method public void setAutoSizeStepGranularity(int, float); + method public void setAutoSizeTextPresetSizes(int[]); method public void setAutoSizeTextType(int); method public void setBreakStrategy(int); method public void setCompoundDrawablePadding(int); diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index 28c5c60686ed..20e325cb6d9e 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -113,6 +113,7 @@ import android.text.style.URLSpan; import android.text.style.UpdateAppearance; import android.text.util.Linkify; import android.util.AttributeSet; +import android.util.IntArray; import android.util.Log; import android.util.TypedValue; import android.view.AccessibilityIterators.TextSegmentIterator; @@ -164,6 +165,8 @@ import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.util.FastMath; import com.android.internal.widget.EditableInputConnection; +import libcore.util.EmptyArray; + import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; @@ -268,6 +271,7 @@ import java.util.Locale; * @attr ref android.R.styleable#TextView_autoSizeMinTextSize * @attr ref android.R.styleable#TextView_autoSizeMaxTextSize * @attr ref android.R.styleable#TextView_autoSizeStepGranularity + * @attr ref android.R.styleable#TextView_autoSizeStepSizeSet */ @RemoteView public class TextView extends View implements ViewTreeObserver.OnPreDrawListener { @@ -715,8 +719,13 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener 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; + // Contains a (specified or computed) distinct sorted set of text sizes in pixels to pick from + // when auto-sizing text. + private int[] mAutoSizeTextSizesInPx = EmptyArray.INT; + // Specifies whether auto-size should use the provided auto size steps set or if it should + // build the steps set using mAutoSizeMinTextSizeInPx, mAutoSizeMaxTextSizeInPx and + // mAutoSizeStepGranularityInPx. + private boolean mHasPredefinedAutoSizeSet = false; // Watcher used to notify changes to auto-fill manager. private AutoFillChangeWatcher mAutoFillChangeWatcher; @@ -1308,8 +1317,19 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener case com.android.internal.R.styleable.TextView_autoSizeMaxTextSize: mAutoSizeMaxTextSizeInPx = a.getDimensionPixelSize(attr, 0); break; + + case com.android.internal.R.styleable.TextView_autoSizeStepSizeSet: + final int autoSizeStepSizeArrayResId = a.getResourceId(attr, 0); + if (autoSizeStepSizeArrayResId > 0) { + final TypedArray autoSizePreDefTextSizes = a.getResources() + .obtainTypedArray(autoSizeStepSizeArrayResId); + setupAutoSizeStepSizeSet(autoSizePreDefTextSizes); + autoSizePreDefTextSizes.recycle(); + } + break; } } + a.recycle(); BufferType bufferType = BufferType.EDITABLE; @@ -1606,7 +1626,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener mAutoSizeMinTextSizeInPx = 0; mAutoSizeMaxTextSizeInPx = 0; mAutoSizeStepGranularityInPx = 0; - mAutoSizeTextSizesInPx = null; + mAutoSizeTextSizesInPx = EmptyArray.INT; mNeedsAutoSizeText = false; } break; @@ -1658,6 +1678,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener if (supportsAutoSizeText()) { mAutoSizeStepGranularityInPx = (int) TypedValue.applyDimension( unit, size, getResources().getDisplayMetrics()); + mHasPredefinedAutoSizeSet = false; setupAutoSizeTextXY(); } } @@ -1690,6 +1711,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener if (supportsAutoSizeText()) { mAutoSizeMinTextSizeInPx = (int) TypedValue.applyDimension( unit, size, getResources().getDisplayMetrics()); + mHasPredefinedAutoSizeSet = false; setupAutoSizeTextXY(); } } @@ -1723,6 +1745,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener if (supportsAutoSizeText()) { mAutoSizeMaxTextSizeInPx = (int) TypedValue.applyDimension( unit, size, getResources().getDisplayMetrics()); + mHasPredefinedAutoSizeSet = false; setupAutoSizeTextXY(); } } @@ -1737,44 +1760,137 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener 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()); + /** + * Sets a predefined array of sizes to be used when auto-sizing. + * + * <ul>Note: + * <li>when <code>presetSizes</code> is not empty then the auto-size algorithm will use the + * values provided here instead of calculating the values based on min, max and step size. Also + * the values will be de-duplicated, sorted and negative or zero values will be removed. + * <li>when <code>presetSizes</code> is empty then the auto-size algorithm will use the min, max + * and step size to build the set of available sizes to choose from. Note that if no values have + * been provided for any of min, max or step size then defaults will be used. + * </ul> + * + * @param presetSizes an {@code int} array of sizes in pixels + * + * @attr ref android.R.styleable#TextView_autoSizeStepSizeSet + * + * @see #getAutoSizeTextPresetSizes() + */ + public void setAutoSizeTextPresetSizes(@NonNull int[] presetSizes) { + if (supportsAutoSizeText()) { + if (presetSizes.length > 0) { + mAutoSizeTextSizesInPx = cleanupAutoSizePredefinedSizes(presetSizes); + final int sizesLength = mAutoSizeTextSizesInPx.length; + mHasPredefinedAutoSizeSet = sizesLength > 0; + if (mHasPredefinedAutoSizeSet) { + mAutoSizeMinTextSizeInPx = mAutoSizeTextSizesInPx[0]; + mAutoSizeMaxTextSizeInPx = mAutoSizeTextSizesInPx[sizesLength - 1]; + mAutoSizeStepGranularityInPx = 0; + } + } else { + mHasPredefinedAutoSizeSet = false; } + setupAutoSizeTextXY(); + } + } - if (mAutoSizeMaxTextSizeInPx <= 0) { - mAutoSizeMaxTextSizeInPx = (int) TypedValue.applyDimension( - TypedValue.COMPLEX_UNIT_SP, - DEFAULT_AUTO_SIZE_MAX_TEXT_SIZE_IN_SP, - getResources().getDisplayMetrics()); - } + /** + * @return the current auto-size {@code int} sizes array (in pixels). + * + * @see #setAutoSizeTextPresetSizes(int[]) + * @see #setAutoSizeMinTextSize(int, float) + * @see #setAutoSizeMaxTextSize(int, float) + * @see #setAutoSizeStepGranularity(int, float) + */ + public int[] getAutoSizeTextPresetSizes() { + return mAutoSizeTextSizesInPx; + } + + private void setupAutoSizeStepSizeSet(TypedArray textSizes) { + final int textSizesLength = textSizes.length(); + final int[] parsedSizes = new int[textSizesLength]; - if (mAutoSizeStepGranularityInPx <= 0) { - mAutoSizeStepGranularityInPx = DEFAULT_AUTO_SIZE_GRANULARITY_IN_PX; + if (textSizesLength > 0) { + for (int i = 0; i < textSizesLength; i++) { + parsedSizes[i] = textSizes.getDimensionPixelSize(i, -1); } + mAutoSizeTextSizesInPx = cleanupAutoSizePredefinedSizes(parsedSizes); + mHasPredefinedAutoSizeSet = mAutoSizeTextSizesInPx.length > 0; + } + } - // 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)"); + // Returns distinct sorted positive values. + private int[] cleanupAutoSizePredefinedSizes(int[] predefinedValues) { + final int predefinedValuesLength = predefinedValues.length; + if (predefinedValuesLength == 0) { + return predefinedValues; + } + Arrays.sort(predefinedValues); + + final IntArray uniqueValidSizes = new IntArray(); + for (int i = 0; i < predefinedValuesLength; i++) { + final int currentPredefinedValue = predefinedValues[i]; + + if (currentPredefinedValue > 0 + && uniqueValidSizes.binarySearch(currentPredefinedValue) < 0) { + uniqueValidSizes.add(currentPredefinedValue); } + } - // Calculate sizes to choose from based on the current auto-size configuration. - final int autoSizeValuesLength = (int) Math.ceil( - (mAutoSizeMaxTextSizeInPx - mAutoSizeMinTextSizeInPx) - / mAutoSizeStepGranularityInPx); + return predefinedValuesLength == uniqueValidSizes.size() + ? predefinedValues + : uniqueValidSizes.toArray(); + } + + private void setupAutoSizeTextXY() { + if (supportsAutoSizeText() && mAutoSizeTextType == AUTO_SIZE_TEXT_TYPE_XY) { + // Calculate the sizes set based on minimum size, maximum size and step size if we do + // not have a predefined set of sizes or if the current sizes array is empty. + if (!mHasPredefinedAutoSizeSet || mAutoSizeTextSizesInPx.length == 0) { + // 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; + } - mAutoSizeTextSizesInPx = new int[autoSizeValuesLength]; - int sizeToAdd = mAutoSizeMinTextSizeInPx; - for (int i = 0; i < autoSizeValuesLength; i++) { - mAutoSizeTextSizesInPx[i] = sizeToAdd; - sizeToAdd += mAutoSizeStepGranularityInPx; + // 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. + int autoSizeValuesLength = (int) Math.ceil( + (mAutoSizeMaxTextSizeInPx - mAutoSizeMinTextSizeInPx) + / (float) mAutoSizeStepGranularityInPx); + // Also reserve a slot for the max size if it fits. + if ((mAutoSizeMaxTextSizeInPx - mAutoSizeMinTextSizeInPx) + % mAutoSizeStepGranularityInPx == 0) { + autoSizeValuesLength++; + } + mAutoSizeTextSizesInPx = new int[autoSizeValuesLength]; + int sizeToAdd = mAutoSizeMinTextSizeInPx; + for (int i = 0; i < autoSizeValuesLength; i++) { + mAutoSizeTextSizesInPx[i] = sizeToAdd; + sizeToAdd += mAutoSizeStepGranularityInPx; + } } mNeedsAutoSizeText = true; @@ -7822,16 +7938,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener scrollTo(0, 0); } - if (isAutoSizeEnabled()) { - 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. - mNeedsAutoSizeText = true; - } - setMeasuredDimension(width, height); } @@ -7839,8 +7945,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener * Automatically computes and sets the text size. */ private void autoSizeText() { - final int maxWidth = getMeasuredWidth() - getTotalPaddingLeft() - getTotalPaddingRight(); - final int maxHeight = getMeasuredHeight() - getTotalPaddingBottom() - getTotalPaddingTop(); + final int maxWidth = getWidth() - getTotalPaddingLeft() - getTotalPaddingRight(); + final int maxHeight = getHeight() - getExtendedPaddingBottom() - getExtendedPaddingTop(); if (maxWidth <= 0 || maxHeight <= 0) { return; @@ -7914,11 +8020,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener return false; } - // Width overflow. - if (layout.getWidth() > availableSpace.right) { - return false; - } - // Height overflow. if (layout.getHeight() > availableSpace.bottom) { return false; @@ -8086,6 +8187,16 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener mDeferScroll = -1; bringPointIntoView(Math.min(curs, mText.length())); } + + if (isAutoSizeEnabled()) { + 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 layout round should set this to false. + mNeedsAutoSizeText = true; + } } private boolean isShowingHint() { |