Why is my Button text forced to ALL CAPS on Lollipop?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Android 5.0 changed the default visual language for many widgets, including buttons. If your label appears in uppercase even though the layout XML uses mixed case, the theme is applying a text transformation rather than changing the stored string.
Why Lollipop Uppercases Button Labels
The behavior comes from Material Design. In the Lollipop era, the default button style enabled textAllCaps so action labels looked more prominent and visually consistent across the system UI. That choice lives in the theme and widget style, not in your actual android:text value.
That distinction matters. If your button text is Sign in, the button still stores Sign in; the view just renders it as SIGN IN. Code that reads the string from resources or logs it still sees the original value.
A simplified version of the behavior looks like this:
If your app inherits from an AppCompat or Material theme, the same idea applies even when the exact style name differs.
How to Turn It Off
You can disable the transformation for one button, for a whole style, or at runtime.
For a single view, set the attribute in layout XML:
If you use Material Components, prefer a reusable style so every matching button behaves the same way:
At runtime, you can also disable the transform in Kotlin:
The runtime approach is useful when a label depends on state, such as Retry versus Retry now, but it should not be your default. Theme and XML changes are easier to keep consistent.
When You Should Keep the Default
Uppercase text is not always wrong. Buttons often represent actions, and short action verbs like SAVE or SEND can stand out well in dense screens. If the rest of the app already follows Material conventions, overriding only a few buttons can make the interface look accidental.
There are also localization concerns. Some languages have casing rules that do not map cleanly to English design assumptions. If you disable all-caps because the transformed text looks awkward in a translated build, that is a good reason. If you disable it just because one screenshot looked unfamiliar, the result can be less consistent than the platform default.
A reasonable rule is simple: use mixed case when it improves readability, brand tone, or localization, and use the default when you want standard Material styling with minimal customization.
Common Pitfalls
A common mistake is changing the string resource to uppercase manually. That works visually, but now the resource itself is harder to reuse, and translators lose the original casing intent. Prefer textAllCaps so presentation stays separate from content.
Another issue is overriding one button in code and forgetting the rest. That creates inconsistent screens where one button reads Cancel and the next reads CONFIRM. If the choice is app-wide, put it in a style or theme.
Developers also mix old Button, AppCompatButton, and MaterialButton widgets in the same layout. Each can inherit styling slightly differently. If one button ignores your change, verify which class you are using and which theme is active.
Summary
- Lollipop-style uppercase buttons come from theme-driven text transformation.
- Your original string is not changed; only the rendered label is transformed.
- Use
android:textAllCaps="false"for a single button or a custom style for broader control. - Runtime changes such as
isAllCaps = falsework, but theme-based solutions are easier to maintain. - Keep the default when it supports consistency, and override it when readability or localization benefits from mixed case.

