How to Adjust Text Font Size to Fit Textview

Auto Scale TextView Text to Fit within Bounds

From June 2018 Android officially started supporting this feature for Android 4.0 (API level 14) and higher.

Check it out at: Autosizing TextViews

With Android 8.0 (API level 26) and higher:

<?xml version="1.0" encoding="utf-8"?>
<TextView
android:layout_width="match_parent"
android:layout_height="200dp"
android:autoSizeTextType="uniform"
android:autoSizeMinTextSize="12sp"
android:autoSizeMaxTextSize="100sp"
android:autoSizeStepGranularity="2sp" />

Programmatically:

setAutoSizeTextTypeUniformWithConfiguration(int autoSizeMinTextSize, int autoSizeMaxTextSize, 
int autoSizeStepGranularity, int unit)

textView.setAutoSizeTextTypeUniformWithConfiguration(
1, 17, 1, TypedValue.COMPLEX_UNIT_DIP);


Android versions prior to Android 8.0 (API level 26):

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">

<TextView
android:layout_width="match_parent"
android:layout_height="200dp"
app:autoSizeTextType="uniform"
app:autoSizeMinTextSize="12sp"
app:autoSizeMaxTextSize="100sp"
app:autoSizeStepGranularity="2sp" />

</LinearLayout>

Programmatically:

TextViewCompat.setAutoSizeTextTypeUniformWithConfiguration(
TextView textView, int autoSizeMinTextSize, int autoSizeMaxTextSize, int autoSizeStepGranularity, int unit)

TextViewCompat.setAutoSizeTextTypeUniformWithConfiguration(textView, 1, 17, 1,
TypedValue.COMPLEX_UNIT_DIP);

Attention: TextView must have layout_width="match_parent" or absolute size!

Increase the font size to fit height TextView Android

Actually, there's some trivial error. As You can seen, in your code there's checks for defaultTextSize and so text font cannot get bigger than it, also there's correction of hi is needed inside align loop, because it blocks searching sizes higher than defaultTextSize.

So, final code which makes font big without limit would looks like the following:

public class FontFitTextView extends TextView {

// Attributes
private Paint mTestPaint;
/** 'Initial' text size */
private float mDefaultTextSize;

public FontFitTextView(final Context context) {
super(context);
initialize();
}

public FontFitTextView(final Context context, final AttributeSet attrs) {
super(context, attrs);
initialize();
}

private void initialize() {
mTestPaint = new Paint();
mTestPaint.set(this.getPaint());
mDefaultTextSize = getTextSize();
}

/*
* Re size the font so the specified text fits in the text box
* assuming the text box is the specified width.
*/
private void refitText(final String text, final int textWidth) {

if(textWidth <= 0 || text.isEmpty()) {
return;
}

int targetWidth = textWidth - this.getPaddingLeft() - this.getPaddingRight();

// this is most likely a non-relevant call
if(targetWidth <= 2) {
return;
}

// text already fits with the xml-defined font size?
mTestPaint.set(this.getPaint());
mTestPaint.setTextSize(mDefaultTextSize);

// adjust text size using binary search for efficiency
float hi = Math.max(mDefaultTextSize, targetWidth);
float lo = 2;
final float threshold = 0.5f; // How close we have to be

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
this.setTextSize(TypedValue.COMPLEX_UNIT_PX, lo);
}

@Override
protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int parentWidth = MeasureSpec.getSize(widthMeasureSpec);
int height = getMeasuredHeight();
refitText(this.getText().toString(), parentWidth);
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());
}

@Override
protected void onSizeChanged(final int w, final int h, final int oldw, final int oldh) {
if (w != oldw || h != oldh) {
refitText(this.getText().toString(), w);
}
}
}

You can test it with the following xml:

<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">

<com.example.TestApp.FontFitTextView
android:layout_width="100dp"
android:layout_height="100dp"
android:id="@+id/textView"
android:layout_centerInParent="true"
android:text="This text is to be resized." />

<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:id="@+id/minus_button"
android:text="-10px"
android:padding="20dp" />

<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_toRightOf="@id/minus_button"
android:id="@+id/plus_button"
android:text="+10px"
android:padding="20dp" />
</RelativeLayout>

And activity:

public class MyActivity extends Activity {

private static final String TAG = "MyActivity";

TextView mTextView = null;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

// Show the layout with the test view
setContentView(R.layout.main);

mTextView = (TextView) findViewById(R.id.textView);

final Button buttonPlus = (Button) findViewById(R.id.plus_button);

buttonPlus.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(final View v) {
changeTextViewSize(10);
}
});

final Button buttonMinus = (Button) findViewById(R.id.minus_button);

buttonMinus.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(final View v) {
changeTextViewSize(-10);
}
});
}

/**
* Changes text size by needed delta
*
* @param delta in px
*/
private void changeTextViewSize(final int delta) {
final ViewGroup.LayoutParams params = mTextView.getLayoutParams();

params.height += delta;
params.width += delta;

mTextView.setLayoutParams(params);
}
}

Font size of TextView in Android application changes on changing font size from native settings

Actually, Settings font size affects only sizes in sp. So all You need to do - define textSize in dp instead of sp, then settings won't change text size in Your app.

Here's a link to the documentation: Dimensions

However please note that the expected behavior is that the fonts in all apps respect the user's preferences. There are many reasons a user might want to adjust the font sizes and some of them might even be medical - visually impaired users. Using dp instead of sp for text might lead to unwillingly discriminating against some of your app's users.

i.e:

android:textSize="32dp"

Scaling textSize in a TextView

Not that I am aware of, sorry.



Related Topics



Leave a reply



Submit