How to adjust text font size to fit textview

175,389

Solution 1

The solution below incorporates all of the suggestions here. It starts with what was originally posted by Dunni. It uses a binary search like gjpc's, but it is a bit more readable. It also include's gregm's bug fixes and a bug-fix of my own.

import android.content.Context;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.widget.TextView;

public class FontFitTextView extends TextView {

    public FontFitTextView(Context context) {
        super(context);
        initialise();
    }

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

    private void initialise() {
        mTestPaint = new Paint();
        mTestPaint.set(this.getPaint());
        //max size defaults to the initially specified text size unless it is too small
    }

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

    @Override
    protected void onMeasure(int widthMeasureSpec, 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 (int w, int h, int oldw, int oldh) {
        if (w != oldw) {
            refitText(this.getText().toString(), w);
        }
    }

    //Attributes
    private Paint mTestPaint;
}

Solution 2

I've written a class that extends TextView and does this. It just uses measureText as you suggest. Basically it has a maximum text size and minimum text size (which can be changed) and it just runs through the sizes between them in decrements of 1 until it finds the biggest one that will fit. Not particularly elegant, but I don't know of any other way.

Here is the code:

import android.content.Context;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.widget.TextView;

public class FontFitTextView extends TextView {

    public FontFitTextView(Context context) {
        super(context);
        initialise();
    }

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

    private void initialise() {
        testPaint = new Paint();
        testPaint.set(this.getPaint());
        //max size defaults to the intially specified text size unless it is too small
        maxTextSize = this.getTextSize();
        if (maxTextSize < 11) {
            maxTextSize = 20;
        }
        minTextSize = 10;
    }

    /* 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) { 
        if (textWidth > 0) {
            int availableWidth = textWidth - this.getPaddingLeft() - this.getPaddingRight();
            float trySize = maxTextSize;

            testPaint.setTextSize(trySize);
            while ((trySize > minTextSize) && (testPaint.measureText(text) > availableWidth)) {
                trySize -= 1;
                if (trySize <= minTextSize) {
                    trySize = minTextSize;
                    break;
                }
                testPaint.setTextSize(trySize);
            }

            this.setTextSize(trySize);
        }
    }

    @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 (int w, int h, int oldw, int oldh) {
        if (w != oldw) {
            refitText(this.getText().toString(), w);
        }
    }

    //Getters and Setters
    public float getMinTextSize() {
        return minTextSize;
    }

    public void setMinTextSize(int minTextSize) {
        this.minTextSize = minTextSize;
    }

    public float getMaxTextSize() {
        return maxTextSize;
    }

    public void setMaxTextSize(int minTextSize) {
        this.maxTextSize = minTextSize;
    }

    //Attributes
    private Paint testPaint;
    private float minTextSize;
    private float maxTextSize;

}

Solution 3

This is speedplane's FontFitTextView, but it only decreases font size if needed to make the text fit, and keeps its font size otherwise. It does not increase the font size to fit height.

public class FontFitTextView extends TextView {

    // Attributes
    private Paint mTestPaint;
    private float defaultTextSize;

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

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

    private void initialize() {
        mTestPaint = new Paint();
        mTestPaint.set(this.getPaint());
        defaultTextSize = 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(String text, 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(defaultTextSize);
        if(mTestPaint.measureText(text) <= targetWidth) {
            this.setTextSize(TypedValue.COMPLEX_UNIT_PX, defaultTextSize);
            return;
        }

        // adjust text size using binary search for efficiency
        float hi = defaultTextSize;
        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(int widthMeasureSpec, 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(int w, int h, int oldw, int oldh) {
        if (w != oldw || h != oldh) {
            refitText(this.getText().toString(), w);
        }
    }

}

Here is an example how it could be used in xml:

<com.your.package.activity.widget.FontFitTextView
    android:id="@+id/my_id"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:text="My Text"
    android:textSize="60sp" />

This would keep the font size to 60sp as long as the text fits in width. If the text is longer, it will decrease font size. In this case, the TextViews height will also change because of height=wrap_content.

If you find any bugs, feel free to edit.

Solution 4

Here is my solution which works on emulator and phones but not very well on Eclipse layout editor. It's inspired from kilaka's code but the size of the text is not obtained from the Paint but from measuring the TextView itself calling measure(0, 0).

The Java class :

public class FontFitTextView extends TextView
{
    private static final float THRESHOLD = 0.5f;

    private enum Mode { Width, Height, Both, None }

    private int minTextSize = 1;
    private int maxTextSize = 1000;

    private Mode mode = Mode.None;
    private boolean inComputation;
    private int widthMeasureSpec;
    private int heightMeasureSpec;

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

    public FontFitTextView(Context context, AttributeSet attrs) {
            this(context, attrs, 0);
    }

    public FontFitTextView(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);

            TypedArray tAttrs = context.obtainStyledAttributes(attrs, R.styleable.FontFitTextView, defStyle, 0);
            maxTextSize = tAttrs.getDimensionPixelSize(R.styleable.FontFitTextView_maxTextSize, maxTextSize);
            minTextSize = tAttrs.getDimensionPixelSize(R.styleable.FontFitTextView_minTextSize, minTextSize);
            tAttrs.recycle();
    }

    private void resizeText() {
            if (getWidth() <= 0 || getHeight() <= 0)
                    return;
            if(mode == Mode.None)
                    return;

            final int targetWidth = getWidth();
            final int targetHeight = getHeight();

            inComputation = true;
            float higherSize = maxTextSize;
            float lowerSize = minTextSize;
            float textSize = getTextSize();
            while(higherSize - lowerSize > THRESHOLD) {
                    textSize = (higherSize + lowerSize) / 2;
                    if (isTooBig(textSize, targetWidth, targetHeight)) {
                            higherSize = textSize; 
                    } else {
                            lowerSize = textSize;
                    }
            }
            setTextSize(TypedValue.COMPLEX_UNIT_PX, lowerSize);
            measure(widthMeasureSpec, heightMeasureSpec);
            inComputation = false;
    }

    private boolean isTooBig(float textSize, int targetWidth, int targetHeight) {
            setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
            measure(0, 0);
            if(mode == Mode.Both)
                    return getMeasuredWidth() >= targetWidth || getMeasuredHeight() >= targetHeight;
            if(mode == Mode.Width)
                    return getMeasuredWidth() >= targetWidth;
            else
                    return getMeasuredHeight() >= targetHeight;
    }

    private Mode getMode(int widthMeasureSpec, int heightMeasureSpec) {
            int widthMode = MeasureSpec.getMode(widthMeasureSpec);
            int heightMode = MeasureSpec.getMode(heightMeasureSpec);
            if(widthMode == MeasureSpec.EXACTLY && heightMode == MeasureSpec.EXACTLY)
                    return Mode.Both;
            if(widthMode == MeasureSpec.EXACTLY)
                    return Mode.Width;
            if(heightMode == MeasureSpec.EXACTLY)
                    return Mode.Height;
            return Mode.None;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            if(!inComputation) {
                    this.widthMeasureSpec = widthMeasureSpec;
                    this.heightMeasureSpec = heightMeasureSpec;
                    mode = getMode(widthMeasureSpec, heightMeasureSpec);
                    resizeText();
            }
    }

    protected void onTextChanged(final CharSequence text, final int start, final int before, final int after) {
            resizeText();
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
            if (w != oldw || h != oldh)
                    resizeText();
    }

    public int getMinTextSize() {
            return minTextSize;
    }

    public void setMinTextSize(int minTextSize) {
            this.minTextSize = minTextSize;
            resizeText();
    }

    public int getMaxTextSize() {
            return maxTextSize;
    }

    public void setMaxTextSize(int maxTextSize) {
            this.maxTextSize = maxTextSize;
            resizeText();
    }
}

The XML attribute file :

<resources>
    <declare-styleable name="FontFitTextView">
        <attr name="minTextSize" format="dimension" />
        <attr name="maxTextSize" format="dimension" />
    </declare-styleable>
</resources>

Check my github for the latest version of this class. I hope it can be useful for someone. If a bug is found or if the code needs explaination, feel free to open an issue on Github.

Solution 5

Thanks a lot to https://stackoverflow.com/users/234270/speedplane. Great answer!

Here is an improved version of his response that also take care of height and comes with a maxFontSize attribute to limit font size (was useful in my case, so I wanted to share it) :

package com.<your_package>;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.widget.TextView;


public class FontFitTextView extends TextView
{

    private Paint mTestPaint;
    private float maxFontSize;
    private static final float MAX_FONT_SIZE_DEFAULT_VALUE = 20f;

    public FontFitTextView(Context context)
    {
        super(context);
        initialise(context, null);
    }

    public FontFitTextView(Context context, AttributeSet attributeSet)
    {
        super(context, attributeSet);
        initialise(context, attributeSet);
    }

    public FontFitTextView(Context context, AttributeSet attributeSet, int defStyle)
    {
        super(context, attributeSet, defStyle);
        initialise(context, attributeSet);
    }

    private void initialise(Context context, AttributeSet attributeSet)
    {
        if(attributeSet!=null)
        {
            TypedArray styledAttributes = context.obtainStyledAttributes(attributeSet, R.styleable.FontFitTextView);
            maxFontSize = styledAttributes.getDimension(R.styleable.FontFitTextView_maxFontSize, MAX_FONT_SIZE_DEFAULT_VALUE);
            styledAttributes.recycle();
        }
        else
        {
            maxFontSize = MAX_FONT_SIZE_DEFAULT_VALUE;
        }

        mTestPaint = new Paint();
        mTestPaint.set(this.getPaint());
        //max size defaults to the initially specified text size unless it is too small
    }

    /* 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 textHeight)
    {
        if (textWidth <= 0)
            return;
        int targetWidth = textWidth - this.getPaddingLeft() - this.getPaddingRight();
        int targetHeight = textHeight - this.getPaddingTop() - this.getPaddingBottom();
        float hi = maxFontSize;
        float lo = 2;
//      final float threshold = 0.5f; // How close we have to be
        final float threshold = 1f; // How close we have to be

        mTestPaint.set(this.getPaint());

        Rect bounds = new Rect();

        while ((hi - lo) > threshold)
        {
            float size = (hi + lo) / 2;
            mTestPaint.setTextSize(size);

            mTestPaint.getTextBounds(text, 0, text.length(), bounds);

            if (bounds.width() >= targetWidth || bounds.height() >= targetHeight)
                hi = size; // too big
            else
                lo = size; // too small

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

Corresponding /res/values/attr.xml file:

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <declare-styleable name="FontFitTextView">
        <attr name="maxFontSize" format="dimension" />
    </declare-styleable>

</resources>

Example:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:res-auto="http://schemas.android.com/apk/res-auto"
    android:id="@+id/home_Layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/background"
    tools:ignore="ContentDescription" >
...

 <com.<your_package>.FontFitTextView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:singleLine="true"
                    android:text="Sample Text"
                    android:textSize="28sp"
                    res-auto:maxFontSize="35sp"/>

...
</RelativeLayout>

To use the new maxFontSize attribute, don't forget to add xmlns:res-auto="http://schemas.android.com/apk/res-auto" as show in the example.

Share:
175,389

Related videos on Youtube

rudas
Author by

rudas

Updated on January 14, 2021

Comments

  • rudas
    rudas over 3 years

    Is there any way in android to adjust the textsize in a textview to fit the space it occupies?

    E.g. I'm using a TableLayout and adding several TextViews to each row. Since I don't want the TextViews to wrap the text I rather see that it lowers the font size of the content.

    Any ideas?

    I have tried measureText, but since I don't know the size of the column it seems troublesome to use. This is the code where I want to change the font size to something that fits

    TableRow row = new TableRow(this);   
    for (int i=0; i < ColumnNames.length; i++) {    
        TextView textColumn = new TextView(this);      
        textColumn.setText(ColumnNames[i]);
        textColumn.setPadding(0, 0, 1, 0);
        textColumn.setTextColor(getResources().getColor(R.drawable.text_default));          
        row.addView(textColumn, new TableRow.LayoutParams()); 
    } 
    table.addView(row, new TableLayout.LayoutParams());  
    
  • Ted Hopp
    Ted Hopp over 13 years
    A binary search would generally be faster than a linear search.
  • Ted Hopp
    Ted Hopp over 13 years
    Instead of a binary search, a simple scaling works pretty well: trySize *= availableWidth / measured_width (then clamped to minTextSize).
  • AlikElzin-kilaka
    AlikElzin-kilaka over 12 years
    Thanks for combining all the feedback. I see that the solution takes only width into consideration. My problem is that the fond exceeds the height.
  • AlikElzin-kilaka
    AlikElzin-kilaka over 12 years
    Oh, it seems to partially work at runtime. On a device ot emulator, the text is cut half way up. On the Eclipse layout editor it looks fine. Any ideas?
  • AlikElzin-kilaka
    AlikElzin-kilaka over 12 years
    How do you incorporate it in a layout xml?
  • Glenn
    Glenn over 12 years
    This code is useful for placing text within an existing view into a constrained size area or you can create your own derived class from TextView and override the onMeasure as shown in other posts. By itself it cannot be used in a layout.
  • Ed Sinek
    Ed Sinek about 12 years
    Works great for me. Thx for posting. How do I introduce an XML attribute to specify hi/lo - and use the attribute value (if it exists - keeping existing values as defaults) in the refitText method?
  • Ed Sinek
    Ed Sinek about 12 years
    this post looks like it will do the trick (adding custom xml attributes for hi/lo): stackoverflow.com/a/8090772/156611
  • RoflcoptrException
    RoflcoptrException almost 12 years
    @speedplane Is there any way to also center this text?
  • android developer
    android developer almost 12 years
    @kilaka , the code you've set on ppl website doesn't exist. please post it here ...
  • sulai
    sulai over 11 years
    How did you use it? I have added an example of how I use it to my answer. I have tested it with various android versions, emulators and ADT Graphical Layout Editor.
  • PearsonArtPhoto
    PearsonArtPhoto over 11 years
    Essentially, I wasn't specifying a specific height. Your onMeasure is allowing the view to take over if it wants. I managed to come up with a solution, changing the last line in the routine to this.setMeasuredDimension(parentWidth, height);
  • sulai
    sulai over 11 years
    Great input, I corrected the code :) Now it works with match_parent and wrap_content.
  • Toni Alvarez
    Toni Alvarez over 11 years
    It's works prefect on my Galaxy Nexus, but I've problems on devices with small screens.
  • yDelouis
    yDelouis over 11 years
    What's your problem on devices with small screens ?
  • Toni Alvarez
    Toni Alvarez over 11 years
    Sorry, the problem is not with small screens, your view is not working in all devices with Android 4.0, emulator included. I opened new issue in your GitHub
  • vault
    vault over 11 years
    I have the same problem as Hilaka, text is cut. See here
  • sulai
    sulai over 11 years
    By simply reading your code, I don't think this will work. Remember, the question was about automatically adjusting the text view's font size to fit into the view. You set a fixed font size.
  • android developer
    android developer about 11 years
    @kilaka This still doesn't work well because it doesn't handle the height of the text well enough. Also, I think that instead of binary search, you can simply use "trySize *= availableWidth / measureTextWidth;" same for height.
  • android developer
    android developer about 11 years
    Sorry, but it still doesn't work on all cases. I also think it doesn't handle multi lines correctly.
  • Pascal
    Pascal about 11 years
    Oh.. Could you give me a case for which it doesn't work? (Multi line is not supported, you are right)
  • android developer
    android developer about 11 years
    Many cases. I've created a random tester just to prove that it's correct. Here's one sample: width of the view:317px, height: 137px , text: "q7Lr" . What I see is this: tinypic.com/view.php?pic=2dv5yf9&s=6 . here's the sample project i've made: mega.co.nz/… . I think that such a view should handle multi line, support any size of fonts, handle the height and not just the width, ... Sadly, none of the samples i've found has worked well.
  • Pascal
    Pascal about 11 years
    ok, definitely not a complete solution. sorry. No time to improve it for the time being.. If you can improve it, do not hesitate to post your solution.
  • android developer
    android developer about 11 years
    I've created a new thread that shows my tests, hoping that someone would be able to make a good solution : stackoverflow.com/questions/16017165/…
  • Zordid
    Zordid about 11 years
    Why do you test for empty string writing "".equals(s) instead of simply s.isEmpty() ?? Or s.length()==0? Don't understand why I can see these equality tests sometimes.
  • sulai
    sulai about 11 years
    Good point @Zordid, just didn't know about string.isEmpty() until now :)
  • Casey Murray
    Casey Murray almost 11 years
    This was a great solution! In case anyone else is new to android development and doesn't quite know how to implement an extended view in XML, it looks like this: <com.example.zengame1.FontFitTextView android:paddingTop="5dip" android:id="@+id/childs_name" android:layout_width="fill_parent" android:layout_height="0dip" android:layout_weight="1" android:layout_gravity="center" android:textSize="@dimen/text_size"/>
  • Andrew Mackenzie
    Andrew Mackenzie over 10 years
    Good answer (but not good enough to get selected?). Should also implement the third constructor for TextView as shown here: file:///Users/andrew/android-sdk-mac_x86/docs/reference/andr‌​oid/widget/TextView.‌​html
  • Pratik Butani
    Pratik Butani over 10 years
    text.isEmpty() Call requires API level 9 (current min is 8): java.lang.String#isEmpty change it to text.equals(null)
  • sulai
    sulai over 10 years
    @PratikButani thanks for pointing this out. the equivalent to text.isEmpty() would be "".equals(text).
  • Ricardo
    Ricardo over 10 years
    Good solution. If you need really big text size for very large screens, increase the initial value of float hi.
  • StuStirling
    StuStirling over 10 years
    Any way to only resize if the text exceeds the parent width? For example I don't want to increase the size of the text if it fits in ok.
  • Rahul Rastogi
    Rahul Rastogi almost 10 years
    Not working in my android 4.4. Text size is not working.
  • AlexGuti
    AlexGuti almost 10 years
    Great work! Got it working also with buttons. To take care of the textview height just set float hi = this.getHeight() - this.getPaddingBottom() - this.getPaddingTop();
  • Dino
    Dino about 9 years
    I am trying to implement this on my widget, but I keep getting no widget? I have posted a help here link I know it is the view.setTextViewText() that is the issue here
  • SMBiggs
    SMBiggs almost 9 years
    Make sure that you check the view's dimensions after it has been drawn. Doing this during onCreate() is too early. I used ViewTreeObserver to make sure the measurements were taken at the right time.
  • LiangWang
    LiangWang over 8 years
    i think it would be more reasonable to do refitText at "onLayout" rather than "onSizeChanged"
  • LiangWang
    LiangWang over 8 years
    in the real world, believe it or not, when resizing is triggered, onMeasure will be called a lot of times (>20). I think it's enough to put refitText into onSizeChanged and onTextChanged. (I tested it on EditText)
  • Foobar
    Foobar over 8 years
    Does this support multiple lines of text?
  • Muhammad
    Muhammad about 8 years
    Can you please have a look at my problem stackoverflow.com/questions/36265448/…
  • user3690202
    user3690202 over 7 years
    I can't believe this has so many up votes when it clearly doesn't work. It completely ignores the height of the text - so for cases where the text is only a couple of characters it is possible for the text to become cut in half because it is too high for the text view.
  • AlexGuti
    AlexGuti over 7 years
    @user3690202, now i use github.com/grantland/android-autofittextview library to achieve this behavior. Good luck!
  • Rafael Lima
    Rafael Lima almost 6 years
    I know is a long time ago and probably nobody will read it but: "why do you need to do binary search if you can very acurately estimate the value?" you can very accurately estimate the optimal size by mTestPaint.set(this.getPaint()); float v = mTestPaint.measureText(text); if (v > targetWidth) hi = hi * targetWidth / v;
  • chari sharma
    chari sharma almost 6 years
    gravity function is not working like : android:gravity="center_vertical|center_horizontal" How can i achieve this?
  • chari sharma
    chari sharma almost 6 years
    all text support only one line , is it possibility to add multiple line.
  • Atul Bhardwaj
    Atul Bhardwaj almost 4 years
    Use app:autoSizeTextType="uniform" for backward compatibility because android:autoSizeTextType="uniform" only work in API Level 26 and higher.
  • Atul Bhardwaj
    Atul Bhardwaj almost 4 years
    Thanks Suraj. This is the best solution
  • Georgiy Chebotarev
    Georgiy Chebotarev almost 4 years
    I checked it on SDK 24 and it doesn't work. Are you sure, that app:.. will works for SDK low 26?
  • Suraj Vaishnav
    Suraj Vaishnav almost 4 years
    Yes, It works as an app namespace provides backward compatibility. There is a detailed article about it, check this maybe it would solve your problem. medium.com/over-engineering/…