Search code examples
androidcolorstextviewandroid-color

Why is TextView textColor automatically adjusted to the background color tone


I recently started to learn Android development. Made a very simple XML layout with just a LinearLayout containing some ImageViews and TextViews. The theme I use in my styles.xml is

Theme.AppCompat.Light.NoActionBar

For the TextViews I did not set a textColor yet, but on my phone the text colors are adjusted automatically and match the respective background colors (only darker for more contrast). I love this effect but I do not have any idea where it comes from.

This is one of the TextViews:

<?xml version="1.0" encoding="utf-8"?>        
<TextView
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_weight="2"
    android:layout_gravity="center_vertical"
    android:textSize="22sp"
    android:textStyle="bold"
    android:text="Enjoy your view!" />

And this is the result (automatic textColors highlighted in red selection):

enter image description here

Which attribute/setting/class or other built-in feature is responsible for that? Does it depend on the phone? Or the theme? Or ...?


Solution

  • The default text color for the Theme.AppCompat.Light themes is slightly translucent, so that's why it looks like it adjusts for each different background color.

    We can have a look through the source to determine the actual values, starting with your chosen theme, which is defined in appcompat's themes.xml:

    <style name="Theme.AppCompat.Light.NoActionBar">
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
    </style>
    

    This inherits from Theme.AppCompat.Light in that same XML:

    <style name="Theme.AppCompat.Light" parent="Base.Theme.AppCompat.Light" />
    

    Base.Theme.AppCompat.Light is located in themes_base.xml:

    <style name="Base.Theme.AppCompat.Light" parent="Base.V7.Theme.AppCompat.Light">
    

    Which leads us to Base.V7.Theme.AppCompat.Light, in the same file:

    <style name="Base.V7.Theme.AppCompat.Light" parent="Platform.AppCompat.Light">
    

    And then to Platform.AppCompat.Light, where we finally get to a color setting:

    <style name="Platform.AppCompat.Light" parent="android:Theme.Light">
        ...
        <!-- Text colors -->
        <item name="android:textColorPrimary">@color/abc_primary_text_material_light</item>
        ...
    

    abc_primary_text_material_light is actually a ColorStateList, which is defined in XML with a <selector> element, and its file is under appcompat's res/color/ directory:

    <selector xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:state_enabled="false" android:color="@color/primary_text_disabled_material_light"/>
        <item android:color="@color/primary_text_default_material_light"/>
    </selector>
    

    At last, we find the default color – primary_text_default_material_light – which is a simple color value defined in res/values/colors_material.xml:

    <!-- 87% black -->
    <color name="primary_text_default_material_light">#de000000</color>
    

    We can see that the alpha channel on the color is not entirely opaque, which explains the observed appearance.