Last active
August 29, 2015 14:06
-
-
Save fhur/d048e325aee76216c096 to your computer and use it in GitHub Desktop.
TextView that automatically adjusts it's size to fit the container.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @author fernandohur but credit goes to <a href="http://stackoverflow.com/questions/2617266/how-to-adjust-text-font-size-to-fit-textview">speedplane</a> | |
*/ | |
public class FontFitTextView extends TextView { | |
private Paint mTestPaint; | |
/** | |
* The minimum font size in pixels | |
*/ | |
private float minFontSize; | |
public FontFitTextView(Context context) { | |
super(context); | |
initialise(); | |
} | |
public FontFitTextView(Context context, AttributeSet attrs) { | |
super(context, attrs); | |
initialise(); | |
} | |
/** | |
* Sets the minimum allowed font size | |
* @param fontSizeDp the font size in dp | |
*/ | |
public void setMinFontSize(int fontSizeDp){ | |
minFontSize = UIHelper.getPixelsFromDp(getContext().getResources(), fontSizeDp); | |
} | |
private void initialise() { | |
mTestPaint = new Paint(); | |
mTestPaint.set(this.getPaint()); | |
//max size defaults to the initially specified text size unless it is too small | |
minFontSize = 0; | |
} | |
/* Re size the font so the specified text fits in the text box | |
* assuming the text box is the specified width. | |
*/ | |
private void refitText(String text, int textWidth, int parentHeight) { | |
if (textWidth <= 0) | |
return; | |
int targetWidth = textWidth - this.getPaddingLeft() - this.getPaddingRight(); | |
float hi = 100; | |
float lo = 2; | |
final float threshold = 0.5f; // How close we have to be | |
mTestPaint.set(this.getPaint()); | |
while ((hi - lo) > threshold) { | |
float size = (hi + lo) / 2; | |
mTestPaint.setTextSize(size); | |
if (mTestPaint.measureText(text) >= targetWidth) | |
hi = size; // too big | |
else | |
lo = size; // too small | |
} | |
// Use lo so that we undershoot rather than overshoot | |
Resources r = getResources(); | |
float px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 16, r.getDisplayMetrics()); | |
this.setTextSize(TypedValue.COMPLEX_UNIT_PX, Math.max(Math.min(lo, px), minFontSize)); | |
} | |
@Override | |
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { | |
super.onMeasure(widthMeasureSpec, heightMeasureSpec); | |
int parentWidth = MeasureSpec.getSize(widthMeasureSpec); | |
int parentHeight = MeasureSpec.getSize(heightMeasureSpec); | |
int height = getMeasuredHeight(); | |
refitText(this.getText().toString(), parentWidth, parentHeight); | |
this.setMeasuredDimension(parentWidth, height); | |
} | |
@Override | |
protected void onTextChanged(final CharSequence text, final int start, final int before, final int after) { | |
refitText(text.toString(), this.getWidth(), this.getHeight()); | |
} | |
@Override | |
protected void onSizeChanged(int w, int h, int oldw, int oldh) { | |
if (w != oldw) { | |
refitText(this.getText().toString(), w, h); | |
} | |
} | |
} |
The UIHelper method is just this
public static float getPixelsFromDp(Resources resources, int dp) {
return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, resources.getDisplayMetrics());
}
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This is a simple class that automatically changes the font's size to better fit the container.
It auto adjusts the
TextView
's font size to the parent's dimensions. You can also specify a minimum font size by callingsetMinFontSize(int)