Skip to content

Instantly share code, notes, and snippets.

@Freshman111
Created March 14, 2019 05:39
Show Gist options
  • Save Freshman111/d66d69efa05fe9966b28cb7c6b78e650 to your computer and use it in GitHub Desktop.
Save Freshman111/d66d69efa05fe9966b28cb7c6b78e650 to your computer and use it in GitHub Desktop.
Custom TextView auto scale TextView dynamically
/**
* ------------new----------------
* fork from https://bitbucket.org/ankri/autoscaletextview
* auto scale TextView dynamically
*
* ------------old----------------
* A custom Text View that lowers the text size when the text is to big for the TextView. Modified version of one found on stackoverflow
*
* @author Andreas Krings - www.ankri.de
* @version 1.0
*/
public class AutoScaleTextView extends AppCompatTextView {
private Paint textPaint;
private float preferredTextSize;
private float minTextSize;
public AutoScaleTextView(Context context) {
this(context, null);
}
public AutoScaleTextView(Context context, AttributeSet attrs) {
this(context, attrs, R.attr.autoScaleTextViewStyle);
// Use this constructor, if you do not want use the default style
// super(context, attrs);
}
public AutoScaleTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
this.textPaint = new Paint();
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.AutoScaleTextView, defStyle, 0);
this.minTextSize = a.getDimension(R.styleable.AutoScaleTextView_minTextSize, 10f);
a.recycle();
this.preferredTextSize = this.getTextSize();
}
/**
* Set the minimum text size for this view
*
* @param minTextSize The minimum text size
*/
public void setMinTextSize(float minTextSize) {
this.minTextSize = minTextSize;
}
/**
* Resize the text so that it fits
*
* @param text The text. Neither <code>null</code> nor empty.
* @param textWidth The width of the TextView. > 0
*/
private void refitText(String text, int textWidth) {
if (textWidth <= 0 || text == null || text.length() == 0)
return;
// the width
int targetWidth = textWidth - this.getPaddingLeft() - this.getPaddingRight();
float tempMinTextSize = this.minTextSize;
float tempPreferredTextSize = this.preferredTextSize;
final float threshold = 0.5f; // How close we have to be
this.textPaint.set(this.getPaint());
while ((tempPreferredTextSize - tempMinTextSize) > threshold) {
float size = (tempPreferredTextSize + tempMinTextSize) / 2;
this.textPaint.setTextSize(size);
if (this.textPaint.measureText(text) >= targetWidth)
tempPreferredTextSize = size; // too big
else
tempMinTextSize = size; // too small
}
// Use min size so that we undershoot rather than overshoot
this.setTextSize(TypedValue.COMPLEX_UNIT_PX, tempMinTextSize);
}
@Override
protected void onTextChanged(final CharSequence text, final int start, final int before, final int after) {
this.refitText(text.toString(), this.getWidth());
}
@Override
protected void onSizeChanged(int width, int height, int oldwidth, int oldheight) {
if (width != oldwidth)
this.refitText(this.getText().toString(), width);
}
}
-------attr--------
<attr name="autoScaleTextViewStyle" format="reference" />
<declare-styleable name="AutoScaleTextView">
<attr name="minTextSize" format="dimension" />
</declare-styleable>
--------layout--------
<com.xxx.xxx.view.AutoScaleTextView
android:text="@string/jellybean"
android:layout_width="@dimen/width"
android:layout_height="@dimen/height"
android:layout_margin="5dp"
android:textSize="16dp"
app:minTextSize="12dp"
/>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment