AutoSizing TextView Implementation for Android

Let us start with an example,

let's say we have a list view which shows 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 work around with fixing height/width to make it happen but we still can't make it perfect. This problem was solved by Autosizing feature of TextView. In this blog, we will learn how can we use it in our app.So, let's get started.

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

TextViews can be configured by following,

  • AutoSizeTextType
  • Granularity
  • Preset Size

AutoSizeTextType :

This property scales the TextView's text on horizontal and vertical axis by ignoring the textsize 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 deault value.

Note: The default dimensions for uniform scaling are minTextSize = 12sp, maxTextSize = 112sp, andgranularity = 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)

In the above image, you can see both TextViews have same size of the container but text length of both are 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 thr above image you can clearly see that 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 if 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 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 programitacally, 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,

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, 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 specifcally 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 array.xml file while scaling.

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

You can refer to official Document here.

Happy Learning :)

Team MindOrks.