Table Of Contents:
Hyphenation in software engineering refers to the process of splitting a word and inserting hyphens in between the syllables of said word, that would otherwise extend beyond a UI element’s end margin. In Android, hyphenation is commonly used in text fields, such as the view-based system’s
EditText or Jetpack Compose’s
Before API 23
Up until API 23 Android OS didn’t have a support for automatic hyphenation. If the length of the word didn’t fit the original line, it would be moved to the next one below, thus, creating a huge space in the original line. This issue was noticed with the introduction of smartwatches, where the width of the screen is far smaller than a regular phone.
So what did Android Developers do to get the hyphenated effect? Soft-hyphen
Some of the popular options are
Thanks to full UTF support on Android, the extensive use of SHY characters in strings.xml made the string reading in IDE unbearable, but gave the desired outcome.
Introduction of auto-hyphenation at API 23
Algorithms and patterns for automatic hyphenation in Android are based on TeX , and are optimized for mobile use. If you’re interested in learning more, there is a fascinating talk about the whole typesetting system in Android.
normalfrequency is often used for informal cases, like short sentences and chat messages. This value indicates light amount of automatic hyphenation.
nonefrequency indicates no automatic hyphenation. However, mid-word breaks may still happen when a word is wider than the layout, and there are no additional valid breaks within it. Note, soft hyphen is ignored in this value, and will not be used as a suggestion for potential line breaks.
fullfrequency is often to display a running text and/or maximum amount of text in a screen with limited space. This value indicates the full amount of automatic hyphenation, that is applicable in typography.
By default hyphenation frequency is set to
. The change of the default frequency happens in the app’s theme.
Change of defaults at API 29
In Android, setting a hyphenation frequency is an expensive operation. Use Android Text Like a Pro video from Android Dev Summit ‘18 explained the process very well. But, if you want to read up instead of watching, below is my essay of the video:
- Top layer:
onMeasure() there is preliminary work which identifies width & height of the text and builds the layout of the textView. These processes then move down to native code to actually measure the text using open source libraries. All in all,
More than 90% of the
onMeasure()function is spent in native code to measure the text itself. *
- Bottom Layer:
First, native code identifies words in the text. Then, for each word’s character it finds the shape and applies it to the character. It then brings all characters together in the word to adjust spacing between them and apply other character sequencing operations. The newly formed shape of the word is cached and used later in the
onDraw() function of the
TextView. The same is then repeated for the rest of the words. So,
More than 90% of native code is spent to shape the text.*
After it finishes text shaping, it applies line-breaking and hyphenation. Because hyphenation creates 2 or more words, native code applies text shaping all over to the newly created words.
Often times, hyphenation is not needed for all TextViews. However the native code still runs the text shaping on them, thus impacting performance of the text layout. So, Android decided to set the default to
starting the API 29 (2019).
New values at API 33
(2022) introduces two more additional values for hyphenation frequency:
. With these values, the final outcome of the hyphenated text is the same as
full respectively, however the speed is different. The
fullfast values use a hyphenation optimized algorithm, that ignores some hyphen character related typographic features, e.g. kerning(aka spacing), therefore speeds up the performance with almost no impact on rendering.
Handling hyphenation has come a long way on Android. If your app heavily relies on hyphenated words, especially in RecyclerView, I’d highly recommend to look into the
class, which moves the text measurement and shaping into a background thread, and returns the final result to a
*the benchmark data is taken from the presentation .