Autosizing TextView Tutorial for Android: Getting Started
In this Android Autosizing TextView tutorial, you’ll learn how to use new TextView properties to build an app with text that autosizes, adapting dynamically to changes in height and width. By Fernando Sproviero.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
Autosizing TextView Tutorial for Android: Getting Started
10 mins
Android has released new properties for TextView
which let you automatically resize text depending on the width and/or height of your text area. In this autosizing TextView
tutorial, you’ll learn how to use this cool new feature.
Mobile apps use TextViews
extensively. Sometimes, the developer has to use a fixed height or width, which makes resizing the font to always display the text challenging.
Starting with Android 8.0 (API level 26), you can set these new autosizing properties with the TextView
class. Thanks to the Support Library 26.0, you can also use these on devices running Android 4.0 (API level 14) or later by using the TextViewCompat
class.
Note: This tutorial assumes you are familiar with the basics of Android and Kotlin. If you are new to Android Development, check out our Android Tutorial for Beginners series. Just need to catch up on Kotlin? Take a look at Kotlin For Android: An Introduction
Note: This tutorial assumes you are familiar with the basics of Android and Kotlin. If you are new to Android Development, check out our Android Tutorial for Beginners series. Just need to catch up on Kotlin? Take a look at Kotlin For Android: An Introduction
Getting Started
The project you’ll work with, Jokes, is an app that shows you a list of jokes. You can pick a joke to create an image with, add other quotes, change the background and share the result with your friends.
Use the Download Materials button at the top or bottom of this tutorial to download the starter project.
Once downloaded, open the starter project in Android Studio 3.2.1 or newer. Build and run it, and you’ll see the following screen:
Selecting one of the jokes brings you to a new screen that shows only the joke you chose. You can add more text and customize the background. You can also move and pinch the TextView
s. When you have finished customizing the page, you can share it with your friends.
You may have noticed that much of the text in the List Screen is sometimes cut off. Also, resizing the text in the Detail Screen doesn’t adjust the font size to the frame of the TextView
.
To fix these problems, you’ll need to modify the code to autosize the TextView
s according to their width and height.
Review the project to familiarize yourself with the files:
- JokeDetailActivity.kt: Shows a single joke and lets you add additional text, customize the background and share.
- joke_item.xml: Is the layout for each of the list items in the List Screen
- activity_detail.xml: Is the layout for the Detail Screen.
Configuring TextView Autosizing Properties
There are three options that you need to consider when configuring the Autosize properties: AutoSizeTextType, Granularity and Preset Sizes. You’ll learn about them in this section.
AutoSizeTextType
If you want to enable autosizing, you need to set the app:autoSizeTextType
property to uniform
in the xml. Otherwise, the default is none
, which disables this autosizing feature.
Open joke_item.xml, which the List Screen uses, and change the emoji TextView
with id @+id/emoji
to include this attribute. It should now look like the following:
<TextView
android:id="@+id/emoji"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_marginStart="8dp"
android:gravity="center"
android:textColor="#000"
app:autoSizeTextType="uniform"
app:layout_constraintBottom_toBottomOf="@+id/jokeText"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="😀" />
Notice that you have added app:autoSizeTextType="uniform"
to enable autosizing.
TextView
to android.support.v7.widget.AppCompatTextView
.
Now, following the same pattern, change the joke TextView
with id @+id/jokeText
to add app:autoSizeTextType="uniform"
. It should now look like this:
<TextView
android:id="@+id/jokeText"
android:layout_width="0dp"
android:layout_height="@dimen/joke_height"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:gravity="center_vertical"
android:textColor="#fff"
app:autoSizeTextType="uniform"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/emoji"
app:layout_constraintTop_toTopOf="parent"
tools:text="Want to hear a joke about construction? I'm still working on it." />
Open activity_detail.xml and change the joke description TextView
with the id @+id/jokeDescription
the same way to be the following:
<TextView
android:id="@+id/jokeDescription"
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_gravity="center"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:background="@color/colorPrimaryDark"
android:gravity="center_vertical"
android:padding="@dimen/joke_margin"
android:textColor="#FFF"
app:autoSizeTextType="uniform"
tools:text="Want to hear a joke about construction? I'm still working on it." />
Build and run the application. You’ll notice that the TextView
s in the List Screen and the Detail Screen now autosize correctly.
However, if you try to add a TextView
in the Detail Screen, it won’t autosize when you pinch the view because it’s added at runtime.
To fix this, open JokeDetailActivity.kt and find the buildTextView()
method. Replace the call to setTextSize(TypedValue.COMPLEX_UNIT_SP, 24f)
with the following:
TextViewCompat.setAutoSizeTextTypeWithDefaults(this,
TextViewCompat.AUTO_SIZE_TEXT_TYPE_UNIFORM)
You’ve replaced the hardcoded font size of 24sp with the uniform AutoSizeTextType, but this time programmatically.
match_parent
or to a specific value in dps, either in xml or programmatically. Using wrap_content
is not recommended because it may produce unexpected results.
Build and run the app again. Select a joke, add some additional text and resize the TextView
. It should now scale properly.
Granularity
If you want to customize the text further, you can set a range by configuring a minimum, maximum and step increment so that the TextView
scales uniformly within the range.
Suppose your UX team has design guidelines that specify that the List Screen should have text with a minimum of 12sp and a maximum of 28sp with steps of 4sp.
Open joke_item.xml and change the joke TextView
with the id @+id/jokeText
to include the following:
app:autoSizeMaxTextSize="28sp"
app:autoSizeMinTextSize="12sp"
app:autoSizeStepGranularity="4sp"
Build and run the application and select a joke. What happens when you change the size of the joke text?
You should also make this change programmatically when new TextView
s are added. Replace the call to setAutoSizeTextTypeWithDefaults()
you added in JokeDetailActivity.ky buildTextView()
with the following:
TextViewCompat.setAutoSizeTextTypeUniformWithConfiguration(this,
12, 28, 4,
TypedValue.COMPLEX_UNIT_SP)
Preset Sizes
Instead of using minimum, maximum and a step increment, you can specify preset values that the TextView
can use when autosizing text.
Create an arrays.xml file under app ▸ src ▸ main ▸ res ▸ values with this content:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<array name="autosize_text_sizes">
<item>12sp</item>
<item>16sp</item>
<item>20sp</item>
<item>24sp</item>
<item>28sp</item>
</array>
</resources>
Here you are using the same step increments as before, except that you can use whatever values you want.
Open joke_item.xml and change the joke TextView
to replace this:
app:autoSizeMaxTextSize="28sp"
app:autoSizeMinTextSize="12sp"
app:autoSizeStepGranularity="4sp"
with this:
app:autoSizePresetSizes="@array/autosize_text_sizes"
To make this change programmatically, change that same line in setAutoSizeTextTypeWithDefaults()
to:
TextViewCompat.setAutoSizeTextTypeUniformWithPresetSizes(this,
intArrayOf(12, 16, 20, 24, 28),
TypedValue.COMPLEX_UNIT_SP)
You can also get the values from the xml file you created by using context.resources.getIntArray(R.array.autosize_text_sizes)
instead of creating the array manually with intArrayOf()
.
Build and run the app and play with resizing the TextView
. Try changing the values in the array, then building and running the app again to see how resizing the TextView
affects the scaling.