2

I am programming an app that shows a lot of verses/poems so text wrapping is not an option for me. I would like the text to be as big as possible (doesn't have to recalculate each time a new text is shown, should just allow the biggest text to fit on the screen) without extending screen size. It should not visually scale or take longer for the text to appear.

Is this possible?

Thanks

1 Answers1

1

I would suggest a simple search for the best point size using the largest text that you need to fit. This can be done once at start-up. (Well, maybe twice—once for landscape and once for portrait). The first step would be to initialize a Paint with the typeface you want to use for display. Then call this function to

public void setBestTextSize(String longestText, int targetWidth, Paint paint) {
    float size = paint.getTextSize(); // initial size
    float w = paint.meaasureText(longestText);
    size = targetWidth * size / w;
    paint.setTextSize(size);
    // test if we overshot
    w = paint.measureText(longestText);
    while (w > targetWidth) {
        --size;
        paint.setTextSize(size);
        w = paint.measureText(longestText);
    }

A binary search in the loop might be theoretically faster, but this should do pretty well since text width does scale approximately linearly with font size and the first step before the loop should get the size pretty close.

An alternative approach, which deals nicely with view size changes, is shown in this thread.

Community
  • 1
  • 1
Ted Hopp
  • 232,168
  • 48
  • 399
  • 521
  • @Lorenz - This works by measuring the horizontal extent of the text at various font sizes and scaling the size so that the extent is no greater than the available width. I'm not sure if it accounts for line breaks; that would depend on how `Paint.measureText` handles line breaks when measuring the text. All I can suggest there is to try it, or else just feed it the longest unbroken line. – Ted Hopp Jan 01 '12 at 16:16
  • @Lorenz - Yes, you would call `setBestTextSize()` instead of `setTextSize()`. The most reliable way of setting the target width would be to override `onLayout` for the view in which the text is to be painted; that receives the actual view dimensions. (You'll need to account for padding yourself.) You can create a Paint object with `new Paint()`. Are you displaying the text in a custom view? – Ted Hopp Jan 02 '12 at 21:06
  • @Lorenz If you're using a TextView (or one if its subclasses), obtain the Paint object by calling `getPaint()`; don't create a new Paint object. I don't have an opinion on what would be a better use experience; I don't have a clear idea of what your app looks like. It might be better to post that question on the [User Experience](http://ux.stackexchange.com/) StackExchange forum. – Ted Hopp Jan 02 '12 at 21:33