Skip to main content

TextView

elegantTextView

Some languages/scripts (such as Arabic, Lao, Myanmar, Tamil, Gujarati, Kannada, Malayalam, Odia, Telugu, and Thai) have larger vertical metrics than other most languages. To make these languages more readable, we can set TextView's elegantTextView to true:

<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:elegantTextHeight="true"
android:text="@string/my_complex_script_text" />

Notice the different between using elegantTextView and not:

⛔️ android:elegantTextView="false"android:elegantTextView="true"

Behavior Changes in Apps Targeting Android 15

For apps targeting Android 15 (API Level 35), elegantTextView is set to true by default.

You can disable elegantTextView by setting it to true (using compact font). However, it is unlikely to be supported in upcoming releases.

No Break Text

In Android 15, we can preserve a given portion of text in the same line to improve readibility. The first way to do this is by using <nobreak> tag in string resource:

<resources>
<string name="long_text">Learn all things about Android in <nobreak>Android Notebook!</nobreak></string>
</resources>

Notice the different between using <nobreak> and not:

⛔️ Without <nobreak>✅ With <nobreak>

The second way to achieve this by using createNoBreakSpan() method:

import android.app.Activity
import android.text.Spannable
import android.text.SpannableString
import android.text.style.LineBreakConfigSpan
import android.widget.TextView

val normalText = "Learn all things about Android in "
val noBreakText = "Android Notebook!"
val finalText = normalText + noBreakText

val span = SpannableString(finalText)
span.setSpan(
LineBreakConfigSpan.createNoBreakSpan(),
finalText.indexOf(noBreakText),
finalText.indexOf(noBreakText) + noBreakText.length,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE,
)
activity.findViewById<TextView>(R.id.text_view).setText(span, TextView.BufferType.SPANNABLE)

No Hyphen Text

In Android 15, we can disable hyphenation for certain portion of text. The first way to do this is by using <nohyphen> tag in string resource:

<resources>
<string name="long_text_hyphen">The 1984 World Snooker Championship was a ranking professional snooker tournament that took place between 21 April and 7 May at the <nohyphen>Crucible Theatre</nohyphen> in Sheffield, England.</string>
</resources>

Notice the different between using <nohyphen> and not (in "Crucible Theater" text):

⛔️ Without <nohyphen>✅ With <nohyphen>

The second way to achieve this by using createNoHyphenationSpan() method:

import android.app.Activity
import android.text.Spannable
import android.text.SpannableString
import android.text.style.LineBreakConfigSpan
import android.widget.TextView

val normalText = "The 1984 World Snooker Championship was a ranking professional snooker tournament that took place between 21 April and 7 May at the "
val noHyphenText = "Crucible Theatre"
val normalText2 = " in Sheffield, England."
val finalString = normalText + noHyphenText + normalText2
val span = SpannableString(finalString)
span.setSpan(
LineBreakConfigSpan.createNoHyphenationSpan(),
finalString.indexOf(noHyphenText),
finalString.indexOf(noHyphenText) + noHyphenText.length,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
)
activity.findViewById<TextView>(R.id.text_view).setText(span, TextView.BufferType.SPANNABLE)

Justification Mode

Android 8.0 (API Level 26) introduced a TextView property to customize our text's justification mode. There are 3 available justification modes:

Justification Mode (for layout resource)ConstantAPI Level
noneJUSTIFICATION_MODE_NONE26
inter_wordJUSTIFICATION_MODE_INTER_WORD26
inter_characterJUSTIFICATION_MODE_INTER_CHARACTER35

Here's how each justification mode differs from each other:

With English TextWith Japanese Text

JUSTIFICATION_MODE_INTER_CHARACTER, introduced in Android 15, is especially useful for languages that use the whitespace character for segmentation, such as Chinese and Japanese.

The first way of setting justification mode is by using justificationMode attribute in our layout resource:

<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:justificationMode="inter_character"
android:text="@string/my_long_text" />

The second way of setting justification mode is by using setJustificationMode() method:

import android.app.Activity
import android.graphics.text.LineBreaker
import android.os.Build
import android.widget.TextView

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
activity.findViewById<TextView>(R.id.textview1).justificationMode = LineBreaker.JUSTIFICATION_MODE_INTER_WORD
}

Line Break Configuration

Android 13 (API Level 33) introduced a way to wrap Japanese and Korean text by Bunsetsu (the smallest unit of words that sounds natural) or phrases, instead of character. Here's the difference between phrase-based line breaks and not:

⛔️ Normal line break✅ Phrase-based line break
(Image Source: developer.android.com)

Phrase-based line break works well for short text, but they don't really work well for long ones. So, in Android 15 (API Level 35), a new line break configuration was introduced that will automatically choose the best line break configuration for your text. Here's an example of how this new configuration will wrap your text based on its length:

Short Text (Will use LINE_BREAK_WORD_STYLE_PHRASE)Long Text (Will use LINE_BREAK_WORD_STYLE_NONE)
(Image Source: developer.android.com)

That leaves us with these 3 line break configurations:

Line Break Configuration (for layout resource)ConstantAPI LevelDescription
noneLINE_BREAK_WORD_STYLE_NONE33No line-break word style is used for line breaking.
phraseLINE_BREAK_WORD_STYLE_PHRASE33Line breaking is based on phrases, which results in text wrapping only on meaningful words. Support for this line-break word style depends on locale. If the current locale does not support phrase-based text wrapping, this setting has no effect.
?LINE_BREAK_WORD_STYLE_AUTO35A special value for the line breaking word style option.
The auto option for the line break word style does some heuristics based on locales and line count.
In Android 15 (API Level 35), auto option does followings: - If at least one locale in the locale list contains Korean script, this option is equivalent to LINE_BREAK_WORD_STYLE_PHRASE. - If not, then if at least one locale in the locale list contains Japanese script, this option is equivalent to LINE_BREAK_WORD_STYLE_PHRASE if the result of its line count is less than 5 lines. - Otherwise, this option is equivalent to LINE_BREAK_WORD_STYLE_NONE.

You can either set your TextView's line break configuration by using the lineBreakWordStyle attribute:

<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:lineBreakWordStyle="phrase"
android:text="@string/my_short_japanese_text" />

Or programmatically by using setLineBreakWordStyle() method:

import android.app.Activity
import android.graphics.text.LineBreakConfig
import android.os.Build
import android.widget.TextView

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
activity.findViewById<TextView>(R.id.textview).lineBreakWordStyle = LineBreakConfig.LINE_BREAK_WORD_STYLE_PHRASE
}

References