Android: How to set Text Font Size relative to PercentLayout / ConstraintLayout

Viewed 2267

Imagine an Activity that has a Percent Layout, so that a perfect square is drawn in the center of the screen, filling the screen. (So, if you have a Pixel XL phone with it's 1440x2560 screen, this would be an activity with a perfect square in the center of the phone, 1440px by 1440px). Note that it should always be a square in the center of the phone, regardless of display (so phone, tablet, watch, and TV).

This is easy to accomplish using a PercentRelativeLayout (API 23) or a ConstraintLayout using layout_constraintGuide_percent. And this technique can be applied to almost any view. That's all great.

But, how should we do the same with Text? For instance, if you want the word "Applesauce" to be centered that box at the same percent scale on any display. Is there a way to set the font size to mimic this behavior. To say that the letter height should always be say, 10% of it's container, or 10% of the width/height of the screen's pixels?


I think this is not AutoFill or AutoSize text inside that box to fit. (i.e., not trying to do https://developer.android.com/preview/features/autosizing-textview.html). I don't think that would work because that would mean putting the word "Hi" in the box would make it larger than the word "Applesause" inside the same box. I want the text size to always remain the same relative to itself, but to scale relative to it's container.

Setting a Text Size using DP/DIP/SP won't work, because that scales based on physical dimensions, which is great for most normal use cases but is the exact opposite of what we want to accomplish here. The text should always be the same size relative to the layout, even if that goes against all sane legibility, and even if that disrespects the users font settings.


Right now, I can do some math to calculate roughly a specific pixel value for text size that gets kind of close. (i.e., a font that should be 30px on a 720px wide screen, should be 60px on a 1440px screen). But I'm having trouble getting this to work with the DPI values. Android is trying to be "too smart", and is drawing a 30px font on a TVDPI screen differently than a 30PX font on an HDPI screen, even though they are the same pixel width.


I'm not sure how to accomplish this on Android. But on Windows UWP XAML, this is accomplished by hard-coding a font to a layout, and then using <Viewbox Stretch="Uniform">, which will resize the child viewport with pixel-perfect accuracy. And in a web browser using CSS3, you can do this with Viewport Sized Typography (1vmin, 1vmax), which isn't identical behaviour, but is close enough for most uses.

My question is, what is the appropriate way to do that using native Android TextViews?

1 Answers
Related