Issue
For years, I've been desperate for Android TextViews to have the "shrink to fit" font size feature that iOS has, and now that autosizing has finally been added I discover that it isn't just "shrink to fit" but it's also "expand to fit" which is really, really not what I was hoping for.
I'm already setting my preferred font size on my TextView (not directly though, I use the built-in styles), the only time I need the font size automatically changed is if the text can't fit inside the given space and I need it to shrink to fit. Unfortunately, what I'm getting is the situation wherein I just need to set the text, let's say, "Kenny" and instead of leaving it at TextAppearance.Medium
because it fits within the given space, it's blowing it up to something like 60sp
font size. Utterly ridiculous.
1) Is there a direct way to tell the auto sizing to "only shrink"? I don't think so, but in case I missed it, I'd love for you to correct me.
2) Assuming there isn't an option for #1, I assume that my only other option is to set autoSizeMaxTextSize
to the same value as my textSize
... but I try to avoid every setting that value directly. I try to rely on the TextAppearance.Small
, TextAppearance.Medium
, and TextAppearance.Large
when at all possible.
So, how can I reference the textSize
value and use it to set the autoSizeMaxTextSize
in my styles?
<style name="Text.Large" parent="TextAppearance.AppCompat.Large">
<item name="autoSizeTextType">uniform</item>
<item name="autoSizeMaxTextSize">?????</item>
</style>
Solution
If someone finds a more elegant solution, please let me know. Until then, I decided to solve it by subclasses AppCompatTextView
and changing the max size in code. The barebones class I'm using is below, if there are any other methods I should override to make sure I'm updating the value whenever the text size changes, please let me know:
public class TextLabel extends AppCompatTextView {
private void updateAutoSizeConfiguration() {
int minsize = TextViewCompat.getAutoSizeMinTextSize(this);
if (minsize < 0) {
minsize = spToPx(12, getContext());
}
int textsize = (int)Math.floor(getTextSize());
int granularity = TextViewCompat.getAutoSizeStepGranularity(this);
if (granularity < 0) {
granularity = spToPx(1, getContext());
}
TextViewCompat.setAutoSizeTextTypeUniformWithConfiguration(this, minsize,
textsize, granularity, TypedValue.COMPLEX_UNIT_PX);
}
public TextLabel(Context context) {
super(context);
updateAutoSizeConfiguration();
}
public TextLabel(Context context, AttributeSet attrs) {
super(context, attrs);
updateAutoSizeConfiguration();
}
public TextLabel(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
updateAutoSizeConfiguration();
}
@Override
public void setTextSize(int unit, float size) {
super.setTextSize(unit, size);
updateAutoSizeConfiguration();
}
@Override
public void setTextAppearance(Context context, int resId) {
super.setTextAppearance(context, resId);
updateAutoSizeConfiguration();
}
}
Answered By - Kenny Wyland