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); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The UIHelper method is just this