0

Super simple question: what is the relationship of font size to screen resolution on adroid? AVD? E.g. if resolution width is 100px and a TextView has 10 monospaced chars in it, if text size is 10px, can i guarantee that the Text will occupy the full screen width?

My specific problem is that I need to scale 10 characters of text, using textSize, to use the full screen width (using textSize alone). If screen resolution is 100 x 100 and I want 10 characters to fully occupy the screen horizontally, why can't I just use:

 DisplayMetrics metrics = getResources().getDisplayMetrics();
 float pixelFontSize = metrics.widthPixels / 10f;
 textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, pixelFontSize);

? In my testing, I get text that is way to small (uses about 1/3 the resolution) on a 280 x 280 wtih 280 dpi AVD, yet on another AVD 360 x 330 hdpi, the code above produce text way too big to fit on one line. ...I mean, sure I could see needing to subtract a small amount from the pixcelFontSize to account for text layout, but my results are all over the place. I must be missing something. First I was messing with density and the scaled measurement dp and sp, but logic would say that given my problem, density has nothing to do with it at all, right?

EDIT, to further show the problem, here is my solution to scale the text to fit the display, using font size, for 7 or 8 AVD's all wear, square round and chin

 switch (metrics.widthPixels) {
            case 280: //280 dpi

                    resolutionMultiplier = .4f;
                    ideoResolutionMultiplier = 0f;

                break;
            case 360: //hdpi
                resolutionMultiplier = .5f;
                ideoResolutionMultiplier = .0f;
                break;
            case 320: //works for round hdpi, chin tvdpi, but the res 320 square 280 dpi too tall....
                if(metrics.xdpi == 280) { 
                    resolutionMultiplier = .45f;
                    ideoResolutionMultiplier = 0f;
                }
                else {
                    resolutionMultiplier = .47f;
                    ideoResolutionMultiplier = 0f;
                }
                break;
            case 400: //280 dpi
                resolutionMultiplier = .55f;
                ideoResolutionMultiplier = 0f;
                break;
            case 480: //360 dpi
                resolutionMultiplier = .71f;
                ideoResolutionMultiplier = 0f;
                break;

        }

        if (mWzTheme.mWordArrays != null
                && mWzTheme.mWordArrays.isIdeographic()) {
            pixelFontSize = (metrics.widthPixels / new Integer(Constants.MAX_LINE_LENGTH_CHINESE_WATCH).floatValue())
                    + (new Integer(Constants.MAX_LINE_LENGTH_WATCH).floatValue() * ideoResolutionMultiplier);
        }
        else {
            pixelFontSize = (metrics.widthPixels / new Integer(Constants.MAX_LINE_LENGTH_WATCH).floatValue())
                    + (new Integer(Constants.MAX_LINE_LENGTH_WATCH).floatValue() * resolutionMultiplier);
        }
tom
  • 2,190
  • 1
  • 23
  • 27
  • Not sure what do you want to achieve with this. If you want to fit a text to the screen then you need to measure the rendered width probably and adjust the font size according to that. Check out this question: http://stackoverflow.com/questions/16017165/auto-fit-textview-for-android/ Also an arithmetic mistake in your calculation: `DisplayMetrics.widthPixels` is an integer, dividing it by another integer (constant 10) gives you rounded result, no matter whether your target variable was a float. Divide it by `10.0f` which will enforce the conversion of the width to float before the operation. – racs Jun 26 '16 at 22:26
  • The link is interesting, but I think a different issue.... what is "rendered width"? In the code above I get the actual (hopefully) pixel width of the display a.k.a. "resolution", divide it by number of chars, then should i be able to use that value as the textsize? And the the text should be as wide as the screen yes? – tom Jun 26 '16 at 22:45
  • We are talking about the same thing: you have 10 chars and you want to fit it to the screen width. It is not that obvious to calculate the width as you are trying to because the font is proportional spaced (an "i" and an "m" is not the same width). Without complex calculations what you could do is measure the text width using (any) font size: https://developer.android.com/reference/android/graphics/Paint.html#measureText%28java.lang.String%29 and then adjust the text size relatively to your space available. This method is not perfect though, characters are adjusted to the font size sometimes. – racs Jun 27 '16 at 02:28
  • it is a bazaar problem racs. first off, i am using a monospaced font. second, we need to think of this theoretically. if android is honest about the use of px (verses dp and sp), then this should be resolved simply with screen resolution divided by number of characers (e.g. 10) and that, or some fraction/multiple of that becomes the textsize (a.k.a. fotn size). but after 20 hrs of tests using AVD i believe i can say definitively, it just does not work like that. why? what is going on theoretically? or are the AVD's simple not accurate in terms of resolution and text size? – tom Jun 27 '16 at 09:11

2 Answers2

1

Try this library:

https://github.com/AndroidDeveloperLB/AutoFitTextView

This will fit the text to the screen exactly. (Not sure if there were any issues with Android Wear target.)

racs
  • 3,974
  • 2
  • 23
  • 26
  • thanks. that is a megaload of code to deal with this. but something tells me you could be right )))). so far, i can scale to 7 or 8 AVDs using resolution alone with a multiplier that changes for screen resolution (that makes no sense, but i am thinking its the AVD's not having real/accurate display drivers ??) and changing font size. i will paste the code above... – tom Jun 27 '16 at 09:49
  • I doubt that the emulator behaves significantly different than the real devices in this regard. I have no explanation why this solution is not working on all devices. Sounds like your calculation is off somehow. – racs Jun 28 '16 at 10:36
1

Here is a simple solution:

Rect bounds = new Rect();
Paint textPaint = textView.getPaint();
textPaint.getTextBounds(text,0,text.length(),bounds);
int height = bounds.height();
int width = bounds.width();

...but still need a guessing algorithm to go from screen resolution to the font size required to fill the screen with x characters...

tom
  • 2,190
  • 1
  • 23
  • 27
  • Oh ya. That works great. I can solve it in 4 guesses regular or ideographic text. Only twist is for non ideographic the leading /trailing font spacing is not included so you have to use float[] widths = new float[1]; textPaint.getTextWidths(mSampleChar, widths); – tom Jun 28 '16 at 23:10