I've been searching for a way of auto fit a text inside a textview. Through my search I've found many solutions like:
But like many others these doesn't solve my problem. They don't work as expected when we use a TextView with multiline.
Basically my goal is this one:
As you can see, the text resizes based on width, height and also pays attention to the line break, creating a multi-line textview. Also be able to change the typeface.
One of my ideas to solve this was something like this:
int size = CONSTANT_MAX_SIZE;
TextView tv = (TextView) findViewById(R.id.textview1)
while(Math.abs(tv.getMeasuredHeight()) >= TEXTVIEW_MAX_HEIGHT) {
size--;
tv.setTextSize(size);
tv.measure(MeasureSpec.UNSPECIFIED,MeasureSpec.UNSPECIFIED);
i++;
}
CONSTANT_MAX_SIZE is a constant that defines the max size of the font (textsize propriety in a TextView)
TEXTVIEW_MAX_HEIGHT is a constant that defines the max size that the textview can have.
This was called every time the text in the textview was changed.
The textview xml was something like this:
<TextView
android:id="@+id/textview1"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:singleLine="false"
android:inputType="textMultiLine"
android:text=""
android:textSize="150sp" />
Since the width would be limited in the XML, only the height of the view needs to be considered since adjusting it android would automatically create a multiline when needed.
Although this is a potential solution isn't working perfectly (far from it) and it doesn't support resize down (when you delete text).
Any sugestions and/or ideas?
Using the idea from nunofmendes, I wrote a derived class of TextView that auto resizes text and supports multiple lines.
You have a pretty good solution on this problem but i took a look at this from a different point of view. I think that the logic is simpler and more understandable at least for the new android developers. The idea is based by inserting the '\n' character between the spaces of the big string. Then, i set the edited string at the textView as the displaying text. So, here is the code..
The parameters are simple. Str is the string that we are going to edit and the variable step defines in how many spaces the method will insert the '/n' character. Then , you just call something like this :
hope this helps many of you that you don't want to go deeper with TextPaint , Rects, and math functions..
The compilable, fixed code: copy-paste this one, not the accepted one, because you need to fix it:)
Need to use, thanks.
Important: You need to consider the scale factor
While I waited for a possible solution to this question, I have been experimenting and trying to figure it out.
The closest solution to this problem was based in a method from paint.
Basically paint has a method called 'breaktext' which:
I combine that with paint 'getTextBounds' which:
So now I can obtain the number of chars that fit in a given width and the height of those chars.
Using a while you can keep moving the removing chars from the string you want to measure and obtain the number of lines (by using a while(index < string.length)) and multiply that by the height obtained in the getTextBounds.
Additionally you will have to add a variable height for each two lines that represent the space between the lines (which is not counted in the getTextBounds).
As an example code, the function to know the height of a multiple line text is something like this:
Note: maxWidth variable is in pixels
Then you will have to call this method inside a while to determine what is the max font size for that height. An example code would be:
Unfortunately this was the only (as far as I know) way I was able to achieve the aspect from the images above.
Hope this can be of help to anyone trying to overcome this obstacle.
A little improved answer of phamducgiam. It shows text with already fitted size, not skretchs after showing. Looks ugly in editor because of starting textSize 100, but works as it should in run. Here's code:
thanks for your solution you are superman! I have implemented your code in derived class of TextView. The code is converted to C# code for Xamarin android. You can easily convert to Java if you need(remove the first constructor for Java).
Here is AXML code