Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to scale/resize text to fit a TextView?

I'm trying to create a method for resizing multi-line text in a TextView such that it fits within the bounds (both the X and Y dimensions) of the TextView.

At present, I have something, but all it does is resize the text such that just the first letter/character of the text fills the dimensions of the TextView (i.e. only the first letter is viewable, and it's huge). I need it to fit all the lines of the text within the bounds of the TextView.

Here is what I have so far:

public static void autoScaleTextViewTextToHeight(TextView tv) {     final float initSize = tv.getTextSize();     //get the width of the view's back image (unscaled)....      float minViewHeight;     if(tv.getBackground()!=null)     {       minViewHeight = tv.getBackground().getIntrinsicHeight();     }     else     {       minViewHeight = 10f;//some min.     }     final float maxViewHeight = tv.getHeight() - (tv.getPaddingBottom()+tv.getPaddingTop())-12;// -12 just to be sure     final String s = tv.getText().toString();      //System.out.println(""+tv.getPaddingTop()+"/"+tv.getPaddingBottom());      if(minViewHeight >0 && maxViewHeight >2)     {       Rect currentBounds = new Rect();       tv.getPaint().getTextBounds(s, 0, s.length(), currentBounds);       //System.out.println(""+initSize);       //System.out.println(""+maxViewHeight);       //System.out.println(""+(currentBounds.height()));        float resultingSize = 1;       while(currentBounds.height() < maxViewHeight)       {         resultingSize ++;         tv.setTextSize(resultingSize);          tv.getPaint().getTextBounds(s, 0, s.length(), currentBounds);         //System.out.println(""+(currentBounds.height()+tv.getPaddingBottom()+tv.getPaddingTop()));         //System.out.println("Resulting: "+resultingSize);       }       if(currentBounds.height()>=maxViewHeight)       {         //just to be sure, reduce the value         tv.setTextSize(resultingSize-1);       }     } } 

I think the problem is in the use of tv.getPaint().getTextBounds(...). It always returns small numbers for the text bounds... small relative to the tv.getWidth() and tv.getHeight() values... even if the text size is far larger than the width or height of the TextView.

like image 802
RyanM Avatar asked Apr 07 '10 22:04

RyanM


People also ask

How do you fit text in TextView?

To use preset sizes to set up the autosizing of TextView in XML, use the android namespace and set the following attributes: Set the autoSizeText attribute to either none or uniform. none is a default value and uniform lets TextView scale uniformly on horizontal and vertical axes.

Which method is used to change the size of the TextView?

setTextSize(float size) method to set the size of text. textView.

Which attribute increase or decrease the font size of TextView?

app:autoSizeMinTextSize=”10sp” using this attribute the TextView will be resized up to the size of 10sp and app:autoSizeStepGranularity=”2sp” using this attribute we are uniformly reducing the size of the TextView as 2sp when it goes out of the screen.


2 Answers

The AutofitTextView library from MavenCentral handles this nicely. The source hosted on Github(1k+ stars) at https://github.com/grantland/android-autofittextview

Add the following to your app/build.gradle

repositories {     mavenCentral() }  dependencies {     implementation 'me.grantland:autofittextview:0.2.+' } 

Enable any View extending TextView in code:

AutofitHelper.create(textView); 

Enable any View extending TextView in XML:

<me.grantland.widget.AutofitLayout     android:layout_width="match_parent"     android:layout_height="wrap_content"     >     <Button         android:layout_width="match_parent"         android:layout_height="wrap_content"         android:singleLine="true"         /> </me.grantland.widget.AutofitLayout> 

Use the built in Widget in code or XML:

<me.grantland.widget.AutofitTextView     android:layout_width="match_parent"     android:layout_height="wrap_content"     android:singleLine="true"     /> 
like image 120
13rac1 Avatar answered Sep 19 '22 20:09

13rac1


New since Android O:

https://developer.android.com/preview/features/autosizing-textview.html

<TextView   android:layout_width="wrap_content"   android:layout_height="wrap_content"   android:autoSizeTextType="uniform"   android:autoSizeMinTextSize="12sp"   android:autoSizeMaxTextSize="100sp"   android:autoSizeStepGranularity="2sp" /> 
like image 39
Javatar Avatar answered Sep 22 '22 20:09

Javatar