From 6b1f46e61bd52bb9c67c3ce352c468028955baeb Mon Sep 17 00:00:00 2001 From: Konrad Janica Date: Fri, 19 Jun 2015 17:31:58 +0930 Subject: [PATCH 1/2] Added height fitting option --- .../me/grantland/widget/AutofitHelper.java | 1165 +++++++++-------- .../me/grantland/widget/AutofitLayout.java | 198 +-- .../me/grantland/widget/AutofitTextView.java | 407 +++--- library/src/main/res/values/attrs.xml | 26 +- 4 files changed, 943 insertions(+), 853 deletions(-) diff --git a/library/src/main/java/me/grantland/widget/AutofitHelper.java b/library/src/main/java/me/grantland/widget/AutofitHelper.java index 90e0b0e..db2c11c 100644 --- a/library/src/main/java/me/grantland/widget/AutofitHelper.java +++ b/library/src/main/java/me/grantland/widget/AutofitHelper.java @@ -1,554 +1,611 @@ -package me.grantland.widget; - -import android.content.Context; -import android.content.res.Resources; -import android.content.res.TypedArray; -import android.os.Build; -import android.text.Editable; -import android.text.Layout; -import android.text.StaticLayout; -import android.text.TextPaint; -import android.text.TextWatcher; -import android.text.method.SingleLineTransformationMethod; -import android.text.method.TransformationMethod; -import android.util.AttributeSet; -import android.util.DisplayMetrics; -import android.util.Log; -import android.util.TypedValue; -import android.view.View; -import android.widget.TextView; - -import java.util.ArrayList; - -/** - * A helper class to enable automatically resizing {@link TextView}`s {@code textSize} to fit - * within its bounds. - * - * @attr ref R.styleable.AutofitTextView_sizeToFit - * @attr ref R.styleable.AutofitTextView_minTextSize - * @attr ref R.styleable.AutofitTextView_precision - */ -public class AutofitHelper { - - private static final String TAG = "AutoFitTextHelper"; - private static final boolean SPEW = false; - - // Minimum size of the text in pixels - private static final int DEFAULT_MIN_TEXT_SIZE = 8; //sp - // How precise we want to be when reaching the target textWidth size - private static final float DEFAULT_PRECISION = 0.5f; - - /** - * Creates a new instance of {@code AutofitHelper} that wraps a {@link TextView} and enables - * automatically sizing the text to fit. - */ - public static AutofitHelper create(TextView view) { - return create(view, null, 0); - } - - /** - * Creates a new instance of {@code AutofitHelper} that wraps a {@link TextView} and enables - * automatically sizing the text to fit. - */ - public static AutofitHelper create(TextView view, AttributeSet attrs) { - return create(view, attrs, 0); - } - - /** - * Creates a new instance of {@code AutofitHelper} that wraps a {@link TextView} and enables - * automatically sizing the text to fit. - */ - public static AutofitHelper create(TextView view, AttributeSet attrs, int defStyle) { - AutofitHelper helper = new AutofitHelper(view); - boolean sizeToFit = true; - if (attrs != null) { - Context context = view.getContext(); - int minTextSize = (int) helper.getMinTextSize(); - float precision = helper.getPrecision(); - - TypedArray ta = context.obtainStyledAttributes( - attrs, - R.styleable.AutofitTextView, - defStyle, - 0); - sizeToFit = ta.getBoolean(R.styleable.AutofitTextView_sizeToFit, sizeToFit); - minTextSize = ta.getDimensionPixelSize(R.styleable.AutofitTextView_minTextSize, - minTextSize); - precision = ta.getFloat(R.styleable.AutofitTextView_precision, precision); - ta.recycle(); - - helper.setMinTextSize(TypedValue.COMPLEX_UNIT_PX, minTextSize) - .setPrecision(precision); - } - helper.setEnabled(sizeToFit); - - return helper; - } - - /** - * Re-sizes the textSize of the TextView so that the text fits within the bounds of the View. - */ - private static void autofit(TextView view, TextPaint paint, float minTextSize, float maxTextSize, - int maxLines, float precision) { - if (maxLines <= 0 || maxLines == Integer.MAX_VALUE) { - // Don't auto-size since there's no limit on lines. - return; - } - - int targetWidth = view.getWidth() - view.getPaddingLeft() - view.getPaddingRight(); - if (targetWidth <= 0) { - return; - } - - CharSequence text = view.getText(); - TransformationMethod method = view.getTransformationMethod(); - if (method != null) { - text = method.getTransformation(text, view); - } - - Context context = view.getContext(); - Resources r = Resources.getSystem(); - DisplayMetrics displayMetrics; - - float size = maxTextSize; - float high = size; - float low = 0; - - if (context != null) { - r = context.getResources(); - } - displayMetrics = r.getDisplayMetrics(); - - paint.set(view.getPaint()); - paint.setTextSize(size); - - if ((maxLines == 1 && paint.measureText(text, 0, text.length()) > targetWidth) - || getLineCount(text, paint, size, targetWidth, displayMetrics) > maxLines) { - size = getAutofitTextSize(text, paint, targetWidth, maxLines, low, high, precision, - displayMetrics); - } - - if (size < minTextSize) { - size = minTextSize; - } - - view.setTextSize(TypedValue.COMPLEX_UNIT_PX, size); - } - - /** - * Recursive binary search to find the best size for the text. - */ - private static float getAutofitTextSize(CharSequence text, TextPaint paint, - float targetWidth, int maxLines, float low, float high, float precision, - DisplayMetrics displayMetrics) { - float mid = (low + high) / 2.0f; - int lineCount = 1; - StaticLayout layout = null; - - paint.setTextSize(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, mid, - displayMetrics)); - - if (maxLines != 1) { - layout = new StaticLayout(text, paint, (int)targetWidth, Layout.Alignment.ALIGN_NORMAL, - 1.0f, 0.0f, true); - lineCount = layout.getLineCount(); - } - - if (SPEW) Log.d(TAG, "low=" + low + " high=" + high + " mid=" + mid + - " target=" + targetWidth + " maxLines=" + maxLines + " lineCount=" + lineCount); - - if (lineCount > maxLines) { - // For the case that `text` has more newline characters than `maxLines`. - if ((high - low) < precision) { - return low; - } - return getAutofitTextSize(text, paint, targetWidth, maxLines, low, mid, precision, - displayMetrics); - } - else if (lineCount < maxLines) { - return getAutofitTextSize(text, paint, targetWidth, maxLines, mid, high, precision, - displayMetrics); - } - else { - float maxLineWidth = 0; - if (maxLines == 1) { - maxLineWidth = paint.measureText(text, 0, text.length()); - } else { - for (int i = 0; i < lineCount; i++) { - if (layout.getLineWidth(i) > maxLineWidth) { - maxLineWidth = layout.getLineWidth(i); - } - } - } - - if ((high - low) < precision) { - return low; - } else if (maxLineWidth > targetWidth) { - return getAutofitTextSize(text, paint, targetWidth, maxLines, low, mid, precision, - displayMetrics); - } else if (maxLineWidth < targetWidth) { - return getAutofitTextSize(text, paint, targetWidth, maxLines, mid, high, precision, - displayMetrics); - } else { - return mid; - } - } - } - - private static int getLineCount(CharSequence text, TextPaint paint, float size, float width, - DisplayMetrics displayMetrics) { - paint.setTextSize(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, size, - displayMetrics)); - StaticLayout layout = new StaticLayout(text, paint, (int)width, - Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, true); - return layout.getLineCount(); - } - - private static int getMaxLines(TextView view) { - int maxLines = -1; // No limit (Integer.MAX_VALUE also means no limit) - - TransformationMethod method = view.getTransformationMethod(); - if (method != null && method instanceof SingleLineTransformationMethod) { - maxLines = 1; - } - else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { - // setMaxLines() and getMaxLines() are only available on android-16+ - maxLines = view.getMaxLines(); - } - - return maxLines; - } - - // Attributes - private TextView mTextView; - private TextPaint mPaint; - /** - * Original textSize of the TextView. - */ - private float mTextSize; - - private int mMaxLines; - private float mMinTextSize; - private float mMaxTextSize; - private float mPrecision; - - private boolean mEnabled; - private boolean mIsAutofitting; - - private ArrayList mListeners; - - private TextWatcher mTextWatcher = new AutofitTextWatcher(); - - private View.OnLayoutChangeListener mOnLayoutChangeListener = - new AutofitOnLayoutChangeListener(); - - private AutofitHelper(TextView view) { - final Context context = view.getContext(); - float scaledDensity = context.getResources().getDisplayMetrics().scaledDensity; - - mTextView = view; - mPaint = new TextPaint(); - setRawTextSize(view.getTextSize()); - - mMaxLines = getMaxLines(view); - mMinTextSize = scaledDensity * DEFAULT_MIN_TEXT_SIZE; - mMaxTextSize = mTextSize; - mPrecision = DEFAULT_PRECISION; - } - - /** - * Adds an {@link OnTextSizeChangeListener} to the list of those whose methods are called - * whenever the {@link TextView}'s {@code textSize} changes. - */ - public AutofitHelper addOnTextSizeChangeListener(OnTextSizeChangeListener listener) { - if (mListeners == null) { - mListeners = new ArrayList(); - } - mListeners.add(listener); - return this; - } - - /** - * Removes the specified {@link OnTextSizeChangeListener} from the list of those whose methods - * are called whenever the {@link TextView}'s {@code textSize} changes. - */ - public AutofitHelper removeOnTextSizeChangeListener(OnTextSizeChangeListener listener) { - if (mListeners != null) { - mListeners.remove(listener); - } - return this; - } - - /** - * Returns the amount of precision used to calculate the correct text size to fit within its - * bounds. - */ - public float getPrecision() { - return mPrecision; - } - - /** - * Set the amount of precision used to calculate the correct text size to fit within its - * bounds. Lower precision is more precise and takes more time. - * - * @param precision The amount of precision. - */ - public AutofitHelper setPrecision(float precision) { - if (mPrecision != precision) { - mPrecision = precision; - - autofit(); - } - return this; - } - - /** - * Returns the minimum size (in pixels) of the text. - */ - public float getMinTextSize() { - return mMinTextSize; - } - - /** - * Set the minimum text size to the given value, interpreted as "scaled pixel" units. This size - * is adjusted based on the current density and user font size preference. - * - * @param size The scaled pixel size. - * - * @attr ref me.grantland.R.styleable#AutofitTextView_minTextSize - */ - public AutofitHelper setMinTextSize(float size) { - return setMinTextSize(TypedValue.COMPLEX_UNIT_SP, size); - } - - /** - * Set the minimum text size to a given unit and value. See TypedValue for the possible - * dimension units. - * - * @param unit The desired dimension unit. - * @param size The desired size in the given units. - * - * @attr ref me.grantland.R.styleable#AutofitTextView_minTextSize - */ - public AutofitHelper setMinTextSize(int unit, float size) { - Context context = mTextView.getContext(); - Resources r = Resources.getSystem(); - - if (context != null) { - r = context.getResources(); - } - - setRawMinTextSize(TypedValue.applyDimension(unit, size, r.getDisplayMetrics())); - return this; - } - - private void setRawMinTextSize(float size) { - if (size != mMinTextSize) { - mMinTextSize = size; - - autofit(); - } - } - - /** - * Returns the maximum size (in pixels) of the text. - */ - public float getMaxTextSize() { - return mMaxTextSize; - } - - /** - * Set the maximum text size to the given value, interpreted as "scaled pixel" units. This size - * is adjusted based on the current density and user font size preference. - * - * @param size The scaled pixel size. - * - * @attr ref android.R.styleable#TextView_textSize - */ - public AutofitHelper setMaxTextSize(float size) { - return setMaxTextSize(TypedValue.COMPLEX_UNIT_SP, size); - } - - /** - * Set the maximum text size to a given unit and value. See TypedValue for the possible - * dimension units. - * - * @param unit The desired dimension unit. - * @param size The desired size in the given units. - * - * @attr ref android.R.styleable#TextView_textSize - */ - public AutofitHelper setMaxTextSize(int unit, float size) { - Context context = mTextView.getContext(); - Resources r = Resources.getSystem(); - - if (context != null) { - r = context.getResources(); - } - - setRawMaxTextSize(TypedValue.applyDimension(unit, size, r.getDisplayMetrics())); - return this; - } - - private void setRawMaxTextSize(float size) { - if (size != mMaxTextSize) { - mMaxTextSize = size; - - autofit(); - } - } - - /** - * @see TextView#getMaxLines() - */ - public int getMaxLines() { - return mMaxLines; - } - - /** - * @see TextView#setMaxLines(int) - */ - public AutofitHelper setMaxLines(int lines) { - if (mMaxLines != lines) { - mMaxLines = lines; - - autofit(); - } - return this; - } - - /** - * Returns whether or not automatically resizing text is enabled. - */ - public boolean isEnabled() { - return mEnabled; - } - - /** - * Set the enabled state of automatically resizing text. - */ - public AutofitHelper setEnabled(boolean enabled) { - if (mEnabled != enabled) { - mEnabled = enabled; - - if (enabled) { - mTextView.addTextChangedListener(mTextWatcher); - mTextView.addOnLayoutChangeListener(mOnLayoutChangeListener); - - autofit(); - } else { - mTextView.removeTextChangedListener(mTextWatcher); - mTextView.removeOnLayoutChangeListener(mOnLayoutChangeListener); - - mTextView.setTextSize(TypedValue.COMPLEX_UNIT_PX, mTextSize); - } - } - return this; - } - - /** - * Returns the original text size of the View. - * - * @see TextView#getTextSize() - */ - public float getTextSize() { - return mTextSize; - } - - /** - * Set the original text size of the View. - * - * @see TextView#setTextSize(float) - */ - public void setTextSize(float size) { - setTextSize(TypedValue.COMPLEX_UNIT_SP, size); - } - - /** - * Set the original text size of the View. - * - * @see TextView#setTextSize(int, float) - */ - public void setTextSize(int unit, float size) { - if (mIsAutofitting) { - // We don't want to update the TextView's actual textSize while we're autofitting - // since it'd get set to the autofitTextSize - return; - } - Context context = mTextView.getContext(); - Resources r = Resources.getSystem(); - - if (context != null) { - r = context.getResources(); - } - - setRawTextSize(TypedValue.applyDimension(unit, size, r.getDisplayMetrics())); - } - - private void setRawTextSize(float size) { - if (mTextSize != size) { - mTextSize = size; - } - } - - private void autofit() { - float oldTextSize = mTextView.getTextSize(); - float textSize; - - mIsAutofitting = true; - autofit(mTextView, mPaint, mMinTextSize, mMaxTextSize, mMaxLines, mPrecision); - mIsAutofitting = false; - - textSize = mTextView.getTextSize(); - if (textSize != oldTextSize) { - sendTextSizeChange(textSize, oldTextSize); - } - } - - private void sendTextSizeChange(float textSize, float oldTextSize) { - if (mListeners == null) { - return; - } - - for (OnTextSizeChangeListener listener : mListeners) { - listener.onTextSizeChange(textSize, oldTextSize); - } - } - - private class AutofitTextWatcher implements TextWatcher { - @Override - public void beforeTextChanged(CharSequence charSequence, int start, int count, int after) { - // do nothing - } - - @Override - public void onTextChanged(CharSequence charSequence, int start, int before, int count) { - autofit(); - } - - @Override - public void afterTextChanged(Editable editable) { - // do nothing - } - } - - private class AutofitOnLayoutChangeListener implements View.OnLayoutChangeListener { - @Override - public void onLayoutChange(View view, int left, int top, int right, int bottom, - int oldLeft, int oldTop, int oldRight, int oldBottom) { - autofit(); - } - } - - /** - * When an object of a type is attached to an {@code AutofitHelper}, its methods will be called - * when the {@code textSize} is changed. - */ - public interface OnTextSizeChangeListener { - /** - * This method is called to notify you that the size of the text has changed to - * {@code textSize} from {@code oldTextSize}. - */ - public void onTextSizeChange(float textSize, float oldTextSize); - } -} +package me.grantland.widget; + +import android.content.Context; +import android.content.res.Resources; +import android.content.res.TypedArray; +import android.os.Build; +import android.text.Editable; +import android.text.Layout; +import android.text.StaticLayout; +import android.text.TextPaint; +import android.text.TextWatcher; +import android.text.method.SingleLineTransformationMethod; +import android.text.method.TransformationMethod; +import android.util.AttributeSet; +import android.util.DisplayMetrics; +import android.util.Log; +import android.util.TypedValue; +import android.view.View; +import android.widget.TextView; + +import java.util.ArrayList; + +/** + * A helper class to enable automatically resizing {@link TextView}`s {@code textSize} to fit + * within its bounds. + * + * @attr ref R.styleable.AutofitTextView_sizeToFit + * @attr ref R.styleable.AutofitTextView_minTextSize + * @attr ref R.styleable.AutofitTextView_precision + */ +public class AutofitHelper { + + private static final String TAG = "AutoFitTextHelper"; + private static final boolean SPEW = false; + + // Minimum size of the text in pixels + private static final int DEFAULT_MIN_TEXT_SIZE = 8; //sp + // How precise we want to be when reaching the target textWidth size + private static final float DEFAULT_PRECISION = 0.5f; + + /** + * Creates a new instance of {@code AutofitHelper} that wraps a {@link TextView} and enables + * automatically sizing the text to fit. + */ + public static AutofitHelper create(TextView view) { + return create(view, null, 0); + } + + /** + * Creates a new instance of {@code AutofitHelper} that wraps a {@link TextView} and enables + * automatically sizing the text to fit. + */ + public static AutofitHelper create(TextView view, AttributeSet attrs) { + return create(view, attrs, 0); + } + + /** + * Creates a new instance of {@code AutofitHelper} that wraps a {@link TextView} and enables + * automatically sizing the text to fit. + */ + public static AutofitHelper create(TextView view, AttributeSet attrs, int defStyle) { + AutofitHelper helper = new AutofitHelper(view); + boolean sizeToFit = true; + boolean heightToFit = false; + if (attrs != null) { + Context context = view.getContext(); + int minTextSize = (int) helper.getMinTextSize(); + float precision = helper.getPrecision(); + + TypedArray ta = context.obtainStyledAttributes( + attrs, + R.styleable.AutofitTextView, + defStyle, + 0); + sizeToFit = ta.getBoolean(R.styleable.AutofitTextView_sizeToFit, sizeToFit); + heightToFit = ta.getBoolean(R.styleable.AutofitTextView_heightToFit, heightToFit); + minTextSize = ta.getDimensionPixelSize(R.styleable.AutofitTextView_minTextSize, + minTextSize); + precision = ta.getFloat(R.styleable.AutofitTextView_precision, precision); + ta.recycle(); + + helper.setMinTextSize(TypedValue.COMPLEX_UNIT_PX, minTextSize) + .setPrecision(precision); + } + helper.setHeightFitting(heightToFit); + helper.setEnabled(sizeToFit); + + return helper; + } + + /** + * Re-sizes the textSize of the TextView so that the text fits within the bounds of the View. + */ + private static void autofit(TextView view, TextPaint paint, float minTextSize, float maxTextSize, + int maxLines, float precision) { + if (maxLines <= 0 || maxLines == Integer.MAX_VALUE) { + // Don't auto-size since there's no limit on lines. + return; + } + + int targetWidth = view.getWidth() - view.getPaddingLeft() - view.getPaddingRight(); + if (targetWidth <= 0) { + return; + } + + CharSequence text = view.getText(); + TransformationMethod method = view.getTransformationMethod(); + if (method != null) { + text = method.getTransformation(text, view); + } + + Context context = view.getContext(); + Resources r = Resources.getSystem(); + DisplayMetrics displayMetrics; + + float size = maxTextSize; + float high = size; + float low = 0; + + if (context != null) { + r = context.getResources(); + } + displayMetrics = r.getDisplayMetrics(); + + paint.set(view.getPaint()); + paint.setTextSize(size); + + if ((maxLines == 1 && paint.measureText(text, 0, text.length()) > targetWidth) + || getLineCount(text, paint, size, targetWidth, displayMetrics) > maxLines) { + size = getAutofitTextSize(text, paint, targetWidth, maxLines, low, high, precision, + displayMetrics); + } + + if (mIsHeightFitting) { + int targetHeight = view.getHeight() - view.getPaddingTop() - view.getPaddingTop(); + if (targetHeight <= 0) { + if (size < minTextSize) { + size = minTextSize; + } + view.setTextSize(TypedValue.COMPLEX_UNIT_PX, size); + return; + } + + float textHeight = getTextHeight(text, paint, targetWidth, size); + textHeight = getTextHeight(text, paint, targetWidth, size); + float heightRatio = targetHeight / textHeight; + float newSize = size * heightRatio; + if (newSize < size) { + size = newSize; + } + + if (size < minTextSize) { + size = minTextSize; + } + } + + view.setTextSize(TypedValue.COMPLEX_UNIT_PX, size); + } + + /** + * Try to fit the text with current size to a static layout to calculate height needed + * by that text size. + * @note Can be put in a loop where text size is gradually decreased etc. + * @return float The height size required by the text. + */ + private static float getTextHeight(CharSequence text, TextPaint paint, int width, float textSize) { + StaticLayout textHeightAdjuster = new StaticLayout(text, paint, width, + Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, true); + return textHeightAdjuster.getHeight(); + } + + /** + * Recursive binary search to find the best size for the text. + */ + private static float getAutofitTextSize(CharSequence text, TextPaint paint, + float targetWidth, int maxLines, float low, float high, float precision, + DisplayMetrics displayMetrics) { + float mid = (low + high) / 2.0f; + int lineCount = 1; + StaticLayout layout = null; + + paint.setTextSize(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, mid, + displayMetrics)); + + if (maxLines != 1) { + layout = new StaticLayout(text, paint, (int)targetWidth, Layout.Alignment.ALIGN_NORMAL, + 1.0f, 0.0f, true); + lineCount = layout.getLineCount(); + } + + if (SPEW) Log.d(TAG, "low=" + low + " high=" + high + " mid=" + mid + + " target=" + targetWidth + " maxLines=" + maxLines + " lineCount=" + lineCount); + + if (lineCount > maxLines) { + // For the case that `text` has more newline characters than `maxLines`. + if ((high - low) < precision) { + return low; + } + return getAutofitTextSize(text, paint, targetWidth, maxLines, low, mid, precision, + displayMetrics); + } + else if (lineCount < maxLines) { + return getAutofitTextSize(text, paint, targetWidth, maxLines, mid, high, precision, + displayMetrics); + } + else { + float maxLineWidth = 0; + if (maxLines == 1) { + maxLineWidth = paint.measureText(text, 0, text.length()); + } else { + for (int i = 0; i < lineCount; i++) { + if (layout.getLineWidth(i) > maxLineWidth) { + maxLineWidth = layout.getLineWidth(i); + } + } + } + + if ((high - low) < precision) { + return low; + } else if (maxLineWidth > targetWidth) { + return getAutofitTextSize(text, paint, targetWidth, maxLines, low, mid, precision, + displayMetrics); + } else if (maxLineWidth < targetWidth) { + return getAutofitTextSize(text, paint, targetWidth, maxLines, mid, high, precision, + displayMetrics); + } else { + return mid; + } + } + } + + private static int getLineCount(CharSequence text, TextPaint paint, float size, float width, + DisplayMetrics displayMetrics) { + paint.setTextSize(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, size, + displayMetrics)); + StaticLayout layout = new StaticLayout(text, paint, (int)width, + Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, true); + return layout.getLineCount(); + } + + private static int getMaxLines(TextView view) { + int maxLines = -1; // No limit (Integer.MAX_VALUE also means no limit) + + TransformationMethod method = view.getTransformationMethod(); + if (method != null && method instanceof SingleLineTransformationMethod) { + maxLines = 1; + } + else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { + // setMaxLines() and getMaxLines() are only available on android-16+ + maxLines = view.getMaxLines(); + } + + return maxLines; + } + + // Attributes + private TextView mTextView; + private TextPaint mPaint; + /** + * Original textSize of the TextView. + */ + private float mTextSize; + + private int mMaxLines; + private float mMinTextSize; + private float mMaxTextSize; + private float mPrecision; + + private boolean mEnabled; + private boolean mIsAutofitting; + private static boolean mIsHeightFitting; + + private ArrayList mListeners; + + private TextWatcher mTextWatcher = new AutofitTextWatcher(); + + private View.OnLayoutChangeListener mOnLayoutChangeListener = + new AutofitOnLayoutChangeListener(); + + private AutofitHelper(TextView view) { + final Context context = view.getContext(); + float scaledDensity = context.getResources().getDisplayMetrics().scaledDensity; + + mTextView = view; + mPaint = new TextPaint(); + setRawTextSize(view.getTextSize()); + + mMaxLines = getMaxLines(view); + mMinTextSize = scaledDensity * DEFAULT_MIN_TEXT_SIZE; + mMaxTextSize = mTextSize; + mPrecision = DEFAULT_PRECISION; + } + + /** + * Adds an {@link OnTextSizeChangeListener} to the list of those whose methods are called + * whenever the {@link TextView}'s {@code textSize} changes. + */ + public AutofitHelper addOnTextSizeChangeListener(OnTextSizeChangeListener listener) { + if (mListeners == null) { + mListeners = new ArrayList(); + } + mListeners.add(listener); + return this; + } + + /** + * Removes the specified {@link OnTextSizeChangeListener} from the list of those whose methods + * are called whenever the {@link TextView}'s {@code textSize} changes. + */ + public AutofitHelper removeOnTextSizeChangeListener(OnTextSizeChangeListener listener) { + if (mListeners != null) { + mListeners.remove(listener); + } + return this; + } + + /** + * Returns the amount of precision used to calculate the correct text size to fit within its + * bounds. + */ + public float getPrecision() { + return mPrecision; + } + + /** + * Set the amount of precision used to calculate the correct text size to fit within its + * bounds. Lower precision is more precise and takes more time. + * + * @param precision The amount of precision. + */ + public AutofitHelper setPrecision(float precision) { + if (mPrecision != precision) { + mPrecision = precision; + + autofit(); + } + return this; + } + + /** + * Returns the minimum size (in pixels) of the text. + */ + public float getMinTextSize() { + return mMinTextSize; + } + + /** + * Set the minimum text size to the given value, interpreted as "scaled pixel" units. This size + * is adjusted based on the current density and user font size preference. + * + * @param size The scaled pixel size. + * + * @attr ref me.grantland.R.styleable#AutofitTextView_minTextSize + */ + public AutofitHelper setMinTextSize(float size) { + return setMinTextSize(TypedValue.COMPLEX_UNIT_SP, size); + } + + /** + * Set the minimum text size to a given unit and value. See TypedValue for the possible + * dimension units. + * + * @param unit The desired dimension unit. + * @param size The desired size in the given units. + * + * @attr ref me.grantland.R.styleable#AutofitTextView_minTextSize + */ + public AutofitHelper setMinTextSize(int unit, float size) { + Context context = mTextView.getContext(); + Resources r = Resources.getSystem(); + + if (context != null) { + r = context.getResources(); + } + + setRawMinTextSize(TypedValue.applyDimension(unit, size, r.getDisplayMetrics())); + return this; + } + + private void setRawMinTextSize(float size) { + if (size != mMinTextSize) { + mMinTextSize = size; + + autofit(); + } + } + + /** + * Returns the maximum size (in pixels) of the text. + */ + public float getMaxTextSize() { + return mMaxTextSize; + } + + /** + * Set the maximum text size to the given value, interpreted as "scaled pixel" units. This size + * is adjusted based on the current density and user font size preference. + * + * @param size The scaled pixel size. + * + * @attr ref android.R.styleable#TextView_textSize + */ + public AutofitHelper setMaxTextSize(float size) { + return setMaxTextSize(TypedValue.COMPLEX_UNIT_SP, size); + } + + /** + * Set the maximum text size to a given unit and value. See TypedValue for the possible + * dimension units. + * + * @param unit The desired dimension unit. + * @param size The desired size in the given units. + * + * @attr ref android.R.styleable#TextView_textSize + */ + public AutofitHelper setMaxTextSize(int unit, float size) { + Context context = mTextView.getContext(); + Resources r = Resources.getSystem(); + + if (context != null) { + r = context.getResources(); + } + + setRawMaxTextSize(TypedValue.applyDimension(unit, size, r.getDisplayMetrics())); + return this; + } + + private void setRawMaxTextSize(float size) { + if (size != mMaxTextSize) { + mMaxTextSize = size; + + autofit(); + } + } + + /** + * @see TextView#getMaxLines() + */ + public int getMaxLines() { + return mMaxLines; + } + + /** + * @see TextView#setMaxLines(int) + */ + public AutofitHelper setMaxLines(int lines) { + if (mMaxLines != lines) { + mMaxLines = lines; + + autofit(); + } + return this; + } + + /** + * Returns whether or not automatically resizing text + * by width and number of lines is enabled. + */ + public boolean isEnabled() { + return mEnabled; + } + + /** + * Set the enabled state of automatically resizing text. + */ + public AutofitHelper setEnabled(boolean enabled) { + if (mEnabled != enabled) { + mEnabled = enabled; + + if (enabled) { + mTextView.addTextChangedListener(mTextWatcher); + mTextView.addOnLayoutChangeListener(mOnLayoutChangeListener); + + autofit(); + } else { + mTextView.removeTextChangedListener(mTextWatcher); + mTextView.removeOnLayoutChangeListener(mOnLayoutChangeListener); + + mTextView.setTextSize(TypedValue.COMPLEX_UNIT_PX, mTextSize); + } + } + return this; + } + + /** + * Returns whether or not automatically resizing text + * by height is enabled. + * @return boolean True when height scaling is on. + */ + public boolean isHeightFitting() { + return mIsHeightFitting; + } + + /** + * Sets the state of automatically resizing by text fitting in height. + * Calls an autofit if it is already enabled. + * @param enabled The state to update the height fitting member + */ + public AutofitHelper setHeightFitting(boolean enabled) { + mIsHeightFitting = enabled; + // Fit if required + setEnabled(mEnabled); + return this; + } + + /** + * Returns the original text size of the View. + * + * @see TextView#getTextSize() + */ + public float getTextSize() { + return mTextSize; + } + + /** + * Set the original text size of the View. + * + * @see TextView#setTextSize(float) + */ + public void setTextSize(float size) { + setTextSize(TypedValue.COMPLEX_UNIT_SP, size); + } + + /** + * Set the original text size of the View. + * + * @see TextView#setTextSize(int, float) + */ + public void setTextSize(int unit, float size) { + if (mIsAutofitting) { + // We don't want to update the TextView's actual textSize while we're autofitting + // since it'd get set to the autofitTextSize + return; + } + Context context = mTextView.getContext(); + Resources r = Resources.getSystem(); + + if (context != null) { + r = context.getResources(); + } + + setRawTextSize(TypedValue.applyDimension(unit, size, r.getDisplayMetrics())); + } + + private void setRawTextSize(float size) { + if (mTextSize != size) { + mTextSize = size; + } + } + + private void autofit() { + float oldTextSize = mTextView.getTextSize(); + float textSize; + + mIsAutofitting = true; + autofit(mTextView, mPaint, mMinTextSize, mMaxTextSize, mMaxLines, mPrecision); + mIsAutofitting = false; + + textSize = mTextView.getTextSize(); + if (textSize != oldTextSize) { + sendTextSizeChange(textSize, oldTextSize); + } + } + + private void sendTextSizeChange(float textSize, float oldTextSize) { + if (mListeners == null) { + return; + } + + for (OnTextSizeChangeListener listener : mListeners) { + listener.onTextSizeChange(textSize, oldTextSize); + } + } + + private class AutofitTextWatcher implements TextWatcher { + @Override + public void beforeTextChanged(CharSequence charSequence, int start, int count, int after) { + // do nothing + } + + @Override + public void onTextChanged(CharSequence charSequence, int start, int before, int count) { + autofit(); + } + + @Override + public void afterTextChanged(Editable editable) { + // do nothing + } + } + + private class AutofitOnLayoutChangeListener implements View.OnLayoutChangeListener { + @Override + public void onLayoutChange(View view, int left, int top, int right, int bottom, + int oldLeft, int oldTop, int oldRight, int oldBottom) { + autofit(); + } + } + + /** + * When an object of a type is attached to an {@code AutofitHelper}, its methods will be called + * when the {@code textSize} is changed. + */ + public interface OnTextSizeChangeListener { + /** + * This method is called to notify you that the size of the text has changed to + * {@code textSize} from {@code oldTextSize}. + */ + public void onTextSizeChange(float textSize, float oldTextSize); + } +} diff --git a/library/src/main/java/me/grantland/widget/AutofitLayout.java b/library/src/main/java/me/grantland/widget/AutofitLayout.java index 7620e70..f7d3df8 100644 --- a/library/src/main/java/me/grantland/widget/AutofitLayout.java +++ b/library/src/main/java/me/grantland/widget/AutofitLayout.java @@ -1,95 +1,103 @@ -package me.grantland.widget; - -import android.content.Context; -import android.content.res.TypedArray; -import android.util.AttributeSet; -import android.util.TypedValue; -import android.view.View; -import android.view.ViewGroup; -import android.widget.FrameLayout; -import android.widget.TextView; - -import java.util.WeakHashMap; - -/** - * A {@link ViewGroup} that re-sizes the text of it's children to be no larger than the width of the - * view. - * - * @attr ref R.styleable.AutofitTextView_sizeToFit - * @attr ref R.styleable.AutofitTextView_minTextSize - * @attr ref R.styleable.AutofitTextView_precision - */ -public class AutofitLayout extends FrameLayout { - - private boolean mEnabled; - private float mMinTextSize; - private float mPrecision; - private WeakHashMap mHelpers = new WeakHashMap(); - - public AutofitLayout(Context context) { - super(context); - init(context, null, 0); - } - - public AutofitLayout(Context context, AttributeSet attrs) { - super(context, attrs); - init(context, attrs, 0); - } - - public AutofitLayout(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - init(context, attrs, defStyle); - } - - private void init(Context context, AttributeSet attrs, int defStyle) { - boolean sizeToFit = true; - int minTextSize = -1; - float precision = -1; - - if (attrs != null) { - TypedArray ta = context.obtainStyledAttributes( - attrs, - R.styleable.AutofitTextView, - defStyle, - 0); - sizeToFit = ta.getBoolean(R.styleable.AutofitTextView_sizeToFit, sizeToFit); - minTextSize = ta.getDimensionPixelSize(R.styleable.AutofitTextView_minTextSize, - minTextSize); - precision = ta.getFloat(R.styleable.AutofitTextView_precision, precision); - ta.recycle(); - } - - mEnabled = sizeToFit; - mMinTextSize = minTextSize; - mPrecision = precision; - } - - @Override - public void addView(View child, int index, ViewGroup.LayoutParams params) { - super.addView(child, index, params); - TextView textView = (TextView) child; - AutofitHelper helper = AutofitHelper.create(textView) - .setEnabled(mEnabled); - if (mPrecision > 0) { - helper.setPrecision(mPrecision); - } - if (mMinTextSize > 0) { - helper.setMinTextSize(TypedValue.COMPLEX_UNIT_PX, mMinTextSize); - } - mHelpers.put(textView, helper); - } - - /** - * Returns the {@link AutofitHelper} for this child View. - */ - public AutofitHelper getAutofitHelper(TextView textView) { - return mHelpers.get(textView); - } - - /** - * Returns the {@link AutofitHelper} for this child View. - */ - public AutofitHelper getAutofitHelper(int index) { - return mHelpers.get(getChildAt(index)); - } -} +package me.grantland.widget; + +import android.content.Context; +import android.content.res.TypedArray; +import android.util.AttributeSet; +import android.util.TypedValue; +import android.view.View; +import android.view.ViewGroup; +import android.widget.FrameLayout; +import android.widget.TextView; + +import com.konradjanica.amatch.R; + +import java.util.WeakHashMap; + +/** + * A {@link ViewGroup} that re-sizes the text of it's children to be no larger than the width of the + * view. + * + * @attr ref R.styleable.AutofitTextView_sizeToFit + * @attr ref R.styleable.AutofitTextView_minTextSize + * @attr ref R.styleable.AutofitTextView_precision + */ +public class AutofitLayout extends FrameLayout { + + private boolean mEnabled; + private boolean mIsHeightFitting; + private float mMinTextSize; + private float mPrecision; + private WeakHashMap mHelpers = new WeakHashMap(); + + public AutofitLayout(Context context) { + super(context); + init(context, null, 0); + } + + public AutofitLayout(Context context, AttributeSet attrs) { + super(context, attrs); + init(context, attrs, 0); + } + + public AutofitLayout(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + init(context, attrs, defStyle); + } + + private void init(Context context, AttributeSet attrs, int defStyle) { + boolean sizeToFit = true; + boolean heightToFit = false; + int minTextSize = -1; + float precision = -1; + + if (attrs != null) { + TypedArray ta = context.obtainStyledAttributes( + attrs, + R.styleable.AutofitTextView, + defStyle, + 0); + sizeToFit = ta.getBoolean(R.styleable.AutofitTextView_sizeToFit, sizeToFit); + heightToFit = ta.getBoolean(R.styleable.AutofitTextView_heightToFit, heightToFit); + minTextSize = ta.getDimensionPixelSize(R.styleable.AutofitTextView_minTextSize, + minTextSize); + precision = ta.getFloat(R.styleable.AutofitTextView_precision, precision); + ta.recycle(); + } + + + mEnabled = sizeToFit; + mIsHeightFitting = heightToFit; + mMinTextSize = minTextSize; + mPrecision = precision; + } + + @Override + public void addView(View child, int index, ViewGroup.LayoutParams params) { + super.addView(child, index, params); + TextView textView = (TextView) child; + AutofitHelper helper = AutofitHelper.create(textView); + helper.setHeightFitting(mIsHeightFitting); + helper.setEnabled(mEnabled); + if (mPrecision > 0) { + helper.setPrecision(mPrecision); + } + if (mMinTextSize > 0) { + helper.setMinTextSize(TypedValue.COMPLEX_UNIT_PX, mMinTextSize); + } + mHelpers.put(textView, helper); + } + + /** + * Returns the {@link AutofitHelper} for this child View. + */ + public AutofitHelper getAutofitHelper(TextView textView) { + return mHelpers.get(textView); + } + + /** + * Returns the {@link AutofitHelper} for this child View. + */ + public AutofitHelper getAutofitHelper(int index) { + return mHelpers.get(getChildAt(index)); + } +} diff --git a/library/src/main/java/me/grantland/widget/AutofitTextView.java b/library/src/main/java/me/grantland/widget/AutofitTextView.java index f5cd9ba..b5b570a 100644 --- a/library/src/main/java/me/grantland/widget/AutofitTextView.java +++ b/library/src/main/java/me/grantland/widget/AutofitTextView.java @@ -1,192 +1,215 @@ -package me.grantland.widget; - -import android.content.Context; -import android.util.AttributeSet; -import android.util.TypedValue; -import android.widget.TextView; - -/** - * A {@link TextView} that re-sizes its text to be no larger than the width of the view. - * - * @attr ref R.styleable.AutofitTextView_sizeToFit - * @attr ref R.styleable.AutofitTextView_minTextSize - * @attr ref R.styleable.AutofitTextView_precision - */ -public class AutofitTextView extends TextView implements AutofitHelper.OnTextSizeChangeListener { - - private AutofitHelper mHelper; - - public AutofitTextView(Context context) { - super(context); - init(context, null, 0); - } - - public AutofitTextView(Context context, AttributeSet attrs) { - super(context, attrs); - init(context, attrs, 0); - } - - public AutofitTextView(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - init(context, attrs, defStyle); - } - - private void init(Context context, AttributeSet attrs, int defStyle) { - mHelper = AutofitHelper.create(this, attrs, defStyle) - .addOnTextSizeChangeListener(this); - } - - // Getters and Setters - - /** - * {@inheritDoc} - */ - @Override - public void setTextSize(int unit, float size) { - super.setTextSize(unit, size); - if (mHelper != null) { - mHelper.setTextSize(unit, size); - } - } - - /** - * {@inheritDoc} - */ - @Override - public void setLines(int lines) { - super.setLines(lines); - if (mHelper != null) { - mHelper.setMaxLines(lines); - } - } - - /** - * {@inheritDoc} - */ - @Override - public void setMaxLines(int maxLines) { - super.setMaxLines(maxLines); - if (mHelper != null) { - mHelper.setMaxLines(maxLines); - } - } - - /** - * Returns the {@link AutofitHelper} for this View. - */ - public AutofitHelper getAutofitHelper() { - return mHelper; - } - - /** - * Returns whether or not the text will be automatically re-sized to fit its constraints. - */ - public boolean isSizeToFit() { - return mHelper.isEnabled(); - } - - /** - * Sets the property of this field (sizeToFit), to automatically resize the text to fit its - * constraints. - */ - public void setSizeToFit() { - setSizeToFit(true); - } - - /** - * If true, the text will automatically be re-sized to fit its constraints; if false, it will - * act like a normal TextView. - * - * @param sizeToFit - */ - public void setSizeToFit(boolean sizeToFit) { - mHelper.setEnabled(sizeToFit); - } - - /** - * Returns the maximum size (in pixels) of the text in this View. - */ - public float getMaxTextSize() { - return mHelper.getMaxTextSize(); - } - - /** - * Set the maximum text size to the given value, interpreted as "scaled pixel" units. This size - * is adjusted based on the current density and user font size preference. - * - * @param size The scaled pixel size. - * - * @attr ref android.R.styleable#TextView_textSize - */ - public void setMaxTextSize(float size) { - mHelper.setMaxTextSize(size); - } - - /** - * Set the maximum text size to a given unit and value. See TypedValue for the possible - * dimension units. - * - * @param unit The desired dimension unit. - * @param size The desired size in the given units. - * - * @attr ref android.R.styleable#TextView_textSize - */ - public void setMaxTextSize(int unit, float size) { - mHelper.setMaxTextSize(unit, size); - } - - /** - * Returns the minimum size (in pixels) of the text in this View. - */ - public float getMinTextSize() { - return mHelper.getMinTextSize(); - } - - /** - * Set the minimum text size to the given value, interpreted as "scaled pixel" units. This size - * is adjusted based on the current density and user font size preference. - * - * @param minSize The scaled pixel size. - * - * @attr ref me.grantland.R.styleable#AutofitTextView_minTextSize - */ - public void setMinTextSize(int minSize) { - mHelper.setMinTextSize(TypedValue.COMPLEX_UNIT_SP, minSize); - } - - /** - * Set the minimum text size to a given unit and value. See TypedValue for the possible - * dimension units. - * - * @param unit The desired dimension unit. - * @param minSize The desired size in the given units. - * - * @attr ref me.grantland.R.styleable#AutofitTextView_minTextSize - */ - public void setMinTextSize(int unit, float minSize) { - mHelper.setMinTextSize(unit, minSize); - } - - /** - * Returns the amount of precision used to calculate the correct text size to fit within its - * bounds. - */ - public float getPrecision() { - return mHelper.getPrecision(); - } - - /** - * Set the amount of precision used to calculate the correct text size to fit within its - * bounds. Lower precision is more precise and takes more time. - * - * @param precision The amount of precision. - */ - public void setPrecision(float precision) { - mHelper.setPrecision(precision); - } - - @Override - public void onTextSizeChange(float textSize, float oldTextSize) { - // do nothing - } -} +package me.grantland.widget; + +import android.content.Context; +import android.util.AttributeSet; +import android.util.TypedValue; +import android.widget.TextView; + +/** + * A {@link TextView} that re-sizes its text to be no larger than the width of the view. + * + * @attr ref R.styleable.AutofitTextView_sizeToFit + * @attr ref R.styleable.AutofitTextView_minTextSize + * @attr ref R.styleable.AutofitTextView_precision + */ +public class AutofitTextView extends TextView implements AutofitHelper.OnTextSizeChangeListener { + + private AutofitHelper mHelper; + + public AutofitTextView(Context context) { + super(context); + init(context, null, 0); + } + + public AutofitTextView(Context context, AttributeSet attrs) { + super(context, attrs); + init(context, attrs, 0); + } + + public AutofitTextView(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + init(context, attrs, defStyle); + } + + private void init(Context context, AttributeSet attrs, int defStyle) { + mHelper = AutofitHelper.create(this, attrs, defStyle) + .addOnTextSizeChangeListener(this); + } + + // Getters and Setters + + /** + * {@inheritDoc} + */ + @Override + public void setTextSize(int unit, float size) { + super.setTextSize(unit, size); + if (mHelper != null) { + mHelper.setTextSize(unit, size); + } + } + + /** + * {@inheritDoc} + */ + @Override + public void setLines(int lines) { + super.setLines(lines); + if (mHelper != null) { + mHelper.setMaxLines(lines); + } + } + + /** + * {@inheritDoc} + */ + @Override + public void setMaxLines(int maxLines) { + super.setMaxLines(maxLines); + if (mHelper != null) { + mHelper.setMaxLines(maxLines); + } + } + + /** + * Returns the {@link AutofitHelper} for this View. + */ + public AutofitHelper getAutofitHelper() { + return mHelper; + } + + /** + * Returns whether or not the text will be automatically re-sized to fit its constraints. + */ + public boolean isSizeToFit() { + return mHelper.isEnabled(); + } + + /** + * Sets the property of this field (sizeToFit), to automatically resize the text to fit its + * constraints. + */ + public void setSizeToFit() { + setSizeToFit(true); + } + + /** + * If true, the text will automatically be re-sized to fit its constraints; if false, it will + * act like a normal TextView. + * + * @param sizeToFit + */ + public void setSizeToFit(boolean sizeToFit) { + mHelper.setEnabled(sizeToFit); + } + + /** + * Returns whether or not the text will be automatically re-sized to fit its height. + */ + public boolean isHeightFitting() { + return mHelper.isHeightFitting(); + } + + /** + * Sets the property of this field (isHeightFitting), to automatically resize the text to fit + * its height. + */ + public void setHeightFitting() { + setHeightFitting(true); + } + + /** + * Enables automatic text resizing to fit the textview height + * @param isEnabled If true, the text will automatically be re-sized to fit its height + */ + public void setHeightFitting(boolean isEnabled) { + mHelper.setHeightFitting(isEnabled); + } + + /** + * Returns the maximum size (in pixels) of the text in this View. + */ + public float getMaxTextSize() { + return mHelper.getMaxTextSize(); + } + + /** + * Set the maximum text size to the given value, interpreted as "scaled pixel" units. This size + * is adjusted based on the current density and user font size preference. + * + * @param size The scaled pixel size. + * + * @attr ref android.R.styleable#TextView_textSize + */ + public void setMaxTextSize(float size) { + mHelper.setMaxTextSize(size); + } + + /** + * Set the maximum text size to a given unit and value. See TypedValue for the possible + * dimension units. + * + * @param unit The desired dimension unit. + * @param size The desired size in the given units. + * + * @attr ref android.R.styleable#TextView_textSize + */ + public void setMaxTextSize(int unit, float size) { + mHelper.setMaxTextSize(unit, size); + } + + /** + * Returns the minimum size (in pixels) of the text in this View. + */ + public float getMinTextSize() { + return mHelper.getMinTextSize(); + } + + /** + * Set the minimum text size to the given value, interpreted as "scaled pixel" units. This size + * is adjusted based on the current density and user font size preference. + * + * @param minSize The scaled pixel size. + * + * @attr ref me.grantland.R.styleable#AutofitTextView_minTextSize + */ + public void setMinTextSize(int minSize) { + mHelper.setMinTextSize(TypedValue.COMPLEX_UNIT_SP, minSize); + } + + /** + * Set the minimum text size to a given unit and value. See TypedValue for the possible + * dimension units. + * + * @param unit The desired dimension unit. + * @param minSize The desired size in the given units. + * + * @attr ref me.grantland.R.styleable#AutofitTextView_minTextSize + */ + public void setMinTextSize(int unit, float minSize) { + mHelper.setMinTextSize(unit, minSize); + } + + /** + * Returns the amount of precision used to calculate the correct text size to fit within its + * bounds. + */ + public float getPrecision() { + return mHelper.getPrecision(); + } + + /** + * Set the amount of precision used to calculate the correct text size to fit within its + * bounds. Lower precision is more precise and takes more time. + * + * @param precision The amount of precision. + */ + public void setPrecision(float precision) { + mHelper.setPrecision(precision); + } + + @Override + public void onTextSizeChange(float textSize, float oldTextSize) { + // do nothing + } +} diff --git a/library/src/main/res/values/attrs.xml b/library/src/main/res/values/attrs.xml index 15e90fe..136b7d1 100644 --- a/library/src/main/res/values/attrs.xml +++ b/library/src/main/res/values/attrs.xml @@ -1,13 +1,15 @@ - - - - - - - - - - - + + + + + + + + + + + + + \ No newline at end of file From 79796d55cbd5437c3a40c7e29a2e853bdaf66843 Mon Sep 17 00:00:00 2001 From: Konrad Janica Date: Fri, 19 Jun 2015 17:34:42 +0930 Subject: [PATCH 2/2] fixed import from working project --- library/src/main/java/me/grantland/widget/AutofitLayout.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/library/src/main/java/me/grantland/widget/AutofitLayout.java b/library/src/main/java/me/grantland/widget/AutofitLayout.java index f7d3df8..a2d17c2 100644 --- a/library/src/main/java/me/grantland/widget/AutofitLayout.java +++ b/library/src/main/java/me/grantland/widget/AutofitLayout.java @@ -9,8 +9,6 @@ import android.widget.FrameLayout; import android.widget.TextView; -import com.konradjanica.amatch.R; - import java.util.WeakHashMap; /**