AutoSizing TextView Implementation for Android

undefined

Let's say we have a list view which shows the name of students in each list item. Names can be of any length starting from 3 characters to n characters, and we want that the text should fill 70% of the screen irrespective of how long is the name.

To do that we have to do some workaround, fixing height/width to make it happen but we still can't make it perfect. This problem was solved by the Autosizing feature of TextView. In this blog, we will learn how can we use it in our app. So, let's get started.

With Android Oreo, Android launched the AutoSizing feature of TextView feature, which means the textview can expand or shrink based on the size provided. Now, this solution can solve the above problem we discussed. This feature is part of the Support Library. Let us break this step by step,

TextViews can be configured by the following:

  • AutoSizeTextType
  • Granularity
  • Preset Size

AutoSizeTextType

This property scales the TextView's text on the horizontal and vertical axis by ignoring the text size property. To use it we use,

app:autoSizeTextType="uniform | none"

Here, uniform means that text will scale uniformly in the given container and none doesn't scale the textview. None is also the default value.

Note : The default dimensions for uniform scaling are minTextSize = 12sp , maxTextSize = 112sp , and granularity = 1px.

To do it programmatically we use,

TextViewCompat.setAutoSizeTextTypeWithDefaults(textview,
    TextViewCompat.AUTO_SIZE_TEXT_TYPE_UNIFORM)

or,

TextViewCompat.setAutoSizeTextTypeWithDefaults(textview,
    TextViewCompat.AUTO_SIZE_TEXT_TYPE_NONE)
undefined

In the above image, you can see both TextViews have the same size as the container but the text length of both is different. Still Hello Mindorks text has auto-sized it to fit itself in the container.

This is the XML layout file for the above,

<LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">

    <TextView
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="100dp"
            android:text="@string/hello_mindorks"
            android:layout_margin="2dp"
            android:textColor="@android:color/white"
            android:gravity="center"
            android:background="@color/colorAccent"
            app:autoSizeTextType="none"/>
    <TextView
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="100dp"
            android:layout_margin="2dp"
            android:gravity="center"
            android:textColor="@android:color/white"
            android:background="@android:color/darker_gray"
            android:text="@string/hello_mindorks"
            app:autoSizeTextType="uniform"/>

</LinearLayout>

As you can see, in TextView - 1, we have used none as autoSizeTextView and uniform in the other, and from the above image, you can clearly see that the first textView has not scaled itself but the second TextView has scaled itself to the size of the container.

This is how we can use autoSizeTextType, to make our textview scalable.

Granularity

This property helps us to take more control over our TextViews for customizing. We can set the minimum and maximum size for the text view and also we can specify the size of each step for this.

Size of Step means , each increment and decrement will happen according to the size of the step.

This can be done by adding the following in TextView,

app:autoSizeMaxTextSize="48sp"
app:autoSizeMinTextSize="8sp"
app:autoSizeStepGranularity="2sp"

In this,

autoSizeMaxTextSize is the maximum size of textview it will take autoSizeMinTextSize is the minimum size of textview it will take and autoSizeStepGranularity is the size of each step.

To do the same programmatically, we use

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

and unit here can be found in TypedValue.

The use of Granularity looks like,

Examp;e Autosizing 2

and XML for above is,

<LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">

    <TextView
            android:layout_width="0dp"
            android:layout_weight="1"
            android:id="@+id/text"
            android:layout_height="100dp"
            android:text="@string/hello_mindorks"
            android:layout_margin="2dp"
            android:textColor="@android:color/white"
            android:gravity="center"
            android:background="@color/colorAccent"
            app:autoSizeMinTextSize="10dp"
            app:autoSizeStepGranularity="20dp"
            app:autoSizeMaxTextSize="100dp"
            app:autoSizeTextType="uniform"/>
    <TextView
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="100dp"
            android:layout_margin="2dp"
            android:gravity="center"
            android:textColor="@android:color/white"
            android:background="@android:color/darker_gray"
            android:text="@string/hello_mindorks"
            app:autoSizeTextType="uniform"/>

</LinearLayout>

Here, the first textview uses the granularity property in it and the second textview doesn't. The difference can be visible in the image above.

Preset Sizes

Last, in the Autosizing of textview is preset size. In this, we specifically provide a size which TextView can use.

to do that we make an XML file, res/values/arrays.xml

<resources>
  <array name="autosize_text_sizes">
    <item>10sp</item>
    <item>12sp</item>
    <item>20sp</item>
    <item>40sp</item>
    <item>100sp</item>
  </array>
</resources>

and we can use this in TextView using,

<?xml version="1.0" encoding="utf-8"?>
<TextView
    android:layout_width="match_parent"
    android:layout_height="200dp"
    android:autoSizeTextType="uniform"
    android:autoSizePresetSizes="@array/autosize_text_sizes" />

and using it using Programmatically,

TextViewCompat.setAutoSizeTextTypeUniformWithPresetSizes(TextView textView, int[] presetSizes, int unit)

and to call the array.xml file,

context.resources.getIntArray(R.array.autosize_text_sizes)

So, now the TextView using Preset Sizes will use only the sizes mentioned in the array.xml file while scaling.

This is all you need to know how to use AutoSizing of TextView.

Happy Learning :)

Team MindOrks.