Auto Scale TextView Text to Fit within Bounds

android, scale, textview, word-wrap

Solution

From June 2018 Android officially started supporting this feature for Android 4.0 (API level 14) and higher. Check it out at: Autosizing TextViews

With Android 8.0 (API level 26) and higher:

<?xml version="1.0" encoding="utf-8"?>
<TextView
    android:layout_width="match_parent"
    android:layout_height="200dp"
    android:autoSizeTextType="uniform"
    android:autoSizeMinTextSize="12sp"
    android:autoSizeMaxTextSize="100sp"
    android:autoSizeStepGranularity="2sp" />

Programmatically:

setAutoSizeTextTypeUniformWithConfiguration(int autoSizeMinTextSize, int autoSizeMaxTextSize, 
        int autoSizeStepGranularity, int unit)

textView.setAutoSizeTextTypeUniformWithConfiguration(
                1, 17, 1, TypedValue.COMPLEX_UNIT_DIP);

Android versions prior to Android 8.0 (API level 26):

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

  <TextView
      android:layout_width="match_parent"
      android:layout_height="200dp"
      app:autoSizeTextType="uniform"
      app:autoSizeMinTextSize="12sp"
      app:autoSizeMaxTextSize="100sp"
      app:autoSizeStepGranularity="2sp" />

</LinearLayout>

Programmatically:

TextViewCompat.setAutoSizeTextTypeUniformWithConfiguration(
TextView textView, int autoSizeMinTextSize, int autoSizeMaxTextSize, int autoSizeStepGranularity, int unit) 

TextViewCompat.setAutoSizeTextTypeUniformWithConfiguration(textView, 1, 17, 1,
TypedValue.COMPLEX_UNIT_DIP);

Attention: TextView must have layout_width="match_parent" or absolute size!

Problem

I'm looking for an optimal way to resize wrapping text in a `TextView` so that it will fit within its getHeight and getWidth bounds. I'm not simply looking for a way to wrap the text- I want to make sure it both wraps and is small enough to fit entirely on the screen. I've seen a few cases on StackOverflow where auto resizing was needed, but they are either very special cases with hack solutions, have no solution, or involve re-drawing the `TextView` recursively until it is small enough (which is memory intense and forces the user to watch the text shrink step-by-step with every recursion). But I'm sure somebody out there has found a good solution that doesn't involve what I'm doing: writing several heavy routines that parse and measure the text, resize the text, and repeat until a suitably small size has been found. What routines does `TextView` use to wrap the text? Couldn't those be somehow used to predict whether text will be small enough? tl;dr: is there a best-practice way to auto-resize a `TextView` to fit, wrapped, in its getHeight and getWidth bounds?

Original source

Related problems