Android
customized button
text color
Android development
UI customization

Android customized button; changing text color

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Changing button text color in Android can be as simple as setting one XML attribute, but real apps usually need state-aware colors for pressed, disabled, or selected buttons. The right solution depends on whether the color is fixed, theme-driven, or updated at runtime.

Set a Static Text Color in XML

If the button should always use one color, define it directly in the layout or through a color resource.

xml
1<Button
2    android:id="@+id/saveButton"
3    android:layout_width="wrap_content"
4    android:layout_height="wrap_content"
5    android:text="Save"
6    android:textColor="@color/button_text_primary" />

And in res/values/colors.xml:

xml
<resources>
    <color name="button_text_primary">#1E3A5F</color>
</resources>

This is the cleanest choice when the button has only one visual state and the color does not depend on interaction.

Use a Color Selector for Different States

Most buttons should not use the same text color in every state. Disabled text should look muted, and pressed text may need higher contrast.

Create a selector in res/color/button_text.xml:

xml
1<?xml version="1.0" encoding="utf-8"?>
2<selector xmlns:android="http://schemas.android.com/apk/res/android">
3    <item android:state_enabled="false" android:color="#9AA5B1" />
4    <item android:state_pressed="true" android:color="#FFFFFF" />
5    <item android:color="#1E3A5F" />
6</selector>

Apply it in the button layout:

xml
1<Button
2    android:id="@+id/submitButton"
3    android:layout_width="wrap_content"
4    android:layout_height="wrap_content"
5    android:text="Submit"
6    android:textColor="@color/button_text" />

The last item acts as the default. Android evaluates the selector from top to bottom and picks the first matching state.

Change the Color Programmatically

If the color depends on app state, change it in code. In modern Android projects, Kotlin is the usual choice.

kotlin
1import android.os.Bundle
2import androidx.appcompat.app.AppCompatActivity
3import androidx.core.content.ContextCompat
4import com.example.app.databinding.ActivityMainBinding
5
6class MainActivity : AppCompatActivity() {
7    private lateinit var binding: ActivityMainBinding
8
9    override fun onCreate(savedInstanceState: Bundle?) {
10        super.onCreate(savedInstanceState)
11        binding = ActivityMainBinding.inflate(layoutInflater)
12        setContentView(binding.root)
13
14        val warningColor = ContextCompat.getColor(this, android.R.color.holo_red_dark)
15        binding.submitButton.setTextColor(warningColor)
16    }
17}

Using ContextCompat.getColor is safer than deprecated older APIs and keeps the code compatible across API levels.

Theme and Material Considerations

If you use MaterialButton, the visible result may also depend on the background tint, ripple, and theme colors. A text color that looks correct on a plain Button can become unreadable on a filled Material component.

In those cases, define text color together with the button style instead of scattering overrides through many layouts.

xml
<style name="AppButton" parent="Widget.MaterialComponents.Button">
    <item name="android:textColor">@color/button_text</item>
</style>

Then apply the style where needed:

xml
1<com.google.android.material.button.MaterialButton
2    style="@style/AppButton"
3    android:layout_width="wrap_content"
4    android:layout_height="wrap_content"
5    android:text="Continue" />

That keeps the behavior consistent and makes theme changes easier.

Reuse Colors Through Styles Instead of Copying Values

Hard-coded hex values scattered through layouts become difficult to maintain. A better pattern is to keep the actual colors in resources and let layouts reference either a selector or a shared style. That way, a theme adjustment only changes one file instead of dozens of buttons.

For example, a style can combine text color with padding and typography so the button remains consistent across screens:

xml
1<style name="PrimaryActionButton" parent="Widget.AppCompat.Button">
2    <item name="android:textColor">@color/button_text</item>
3    <item name="android:textStyle">bold</item>
4    <item name="android:minHeight">48dp</item>
5</style>

Then the layout only needs to apply the style. That keeps visual changes predictable and reduces accidental inconsistencies between XML and runtime code.

Common Pitfalls

A common mistake is setting a plain color when the button really needs a ColorStateList. The result looks fine until the button becomes disabled or pressed.

Another issue is overriding text color directly on one screen while the rest of the app uses styles. That makes UI maintenance harder and can produce inconsistent contrast.

The third problem is forgetting that the background matters. A correct text color on a light button may be unreadable after a theme or background tint change.

Summary

  • Use android:textColor for a single fixed color.
  • Use a selector resource when button states need different colors.
  • Change text color in Kotlin when it depends on runtime logic.
  • Prefer styles for reusable Material or AppCompat button designs.
  • Always check the final contrast against the actual button background.

Course illustration
Course illustration

All Rights Reserved.