Created
March 14, 2019 05:39
-
-
Save Freshman111/d66d69efa05fe9966b28cb7c6b78e650 to your computer and use it in GitHub Desktop.
Custom TextView auto scale TextView dynamically
This file contains 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
/** | |
* ------------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