johannes
johannes

Reputation: 7272

How to use textColorPrimary as background color in a style?

I want to create a style which uses the android textColorPrimary as a background color. I tried the following which does not work, the result is my layout not beeing displayed at all.

<style name="horizontalLine">
    <item name="android:layout_width">fill_parent</item>
    <item name="android:layout_height">1dp</item>
    <item name="android:background">?android:attr/textColorPrimary</item>
</style>

How do I use textColorPrimary as background color in a style?

Upvotes: 11

Views: 11671

Answers (4)

Adil Hussain
Adil Hussain

Reputation: 32103

To apply the ?android:attr/textColorPrimary attribute as the background of a view, you have two options.

First Option

The first option is to define a shape drawable which gets its color from the ?android:attr/textColorPrimary attribute, as follows...

<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
    <solid android:color="?android:attr/textColorPrimary" />
</shape>

... and, assuming you've named this drawable rectangle_shape_with_primary_text_color.xml and placed it in your application's res/drawable folder, you can set it as the background of your style as follows...

<item name="android:background">@drawable/rectangle_shape_with_primary_text_color</item>

... or set it as the background of your view directly, as follows...

android:background="@drawable/rectangle_shape_with_primary_text_color"

Second option

The second option is to set the backgroundTint property of your style or view.

You can set the backgroundTint property of your style as follows:

<style name="horizontalLine">
    <item name="android:background">@android:color/white</item>
    <item name="android:backgroundTint">?android:attr/textColorPrimary</item>
</style>

Or you can set the backgroundTint property of your view directly as follows:

<View
    android:id="@+id/horizontalLine"
    android:layout_width="match_parent"
    android:layout_height="1dp"
    android:background="@android:color/white"
    android:backgroundTint="?android:attr/textColorPrimary" />

Note that the exact value of the background property with this approach is not important but it must be set and it cannot be set to @null or @android:color/transparent.

Upvotes: 3

user2424511
user2424511

Reputation: 335

The error message I get for this is:

org.xmlpull.v1.XmlPullParserException: Binary XML file line #18: <item> tag requires a 'drawable' attribute or child tag defining a drawable

Doing a little digging, the specs say the background attribute should support either a colour, or reference to a drawable resource:

... Looking at the resource you're referencing, it is a StateListDrawable.

platforms/android-17/data/res/color/primary_text_dark.xml

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_enabled="false" android:color="@android:color/bright_foreground_dark_disabled"/>
    <item android:state_window_focused="false" android:color="@android:color/bright_foreground_dark"/>
    <item android:state_pressed="true" android:color="@android:color/bright_foreground_dark_inverse"/>
    <item android:state_selected="true" android:color="@android:color/bright_foreground_dark_inverse"/>
    <item android:state_activated="true" android:color="@android:color/bright_foreground_dark_inverse"/>
    <item android:color="@android:color/bright_foreground_dark"/> <!-- not selected -->
</selector>

However, the docs for StateListDrawable also explicitly say the drawable attribute must be defined for item elements:

https://developer.android.com/guide/topics/resources/drawable-resource.html

<item>
    Defines a drawable to use during certain states, as described by its attributes. Must be a child of a <selector> element.

    attributes:

    android:drawable
        Drawable resource. Required. Reference to a drawable resource.

... which isn't the case for the case for primary_text_dark.xml. So, it's not working because the drawable you're referencing doesn't seem to conform to the spec.

I think the workaround is to reference the colour that's used in primary_text_dark for the default state: bright_foreground_dark. Seeing as that's not public, you need to go directly to the one it references, which is:

android:background="@android:color/background_light"

Upvotes: 2

antonyt
antonyt

Reputation: 21883

This syntax seems to work for me, when trying to use attributes:

<TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:textColor="?android:textColorPrimary"
        android:text="Hello"/>

(or)

<style name="MyStyle">
   <item name="android:textColor">?android:textColorPrimary</item>
</style>

I can change the app theme from Holo to Holo.Light and the text color will change automatically to fit.

It doesn't work when I set it as a background of a View though - Android will crash complaining that the drawable referenced is a state list that does not specify drawables (it is a state list of colors).

    Caused by: org.xmlpull.v1.XmlPullParserException: Binary XML file line #2: <item> tag requires a 'drawable' attribute or child tag defining a drawable
    at android.graphics.drawable.StateListDrawable.inflate(StateListDrawable.java:178)
    at android.graphics.drawable.Drawable.createFromXmlInner(Drawable.java:885)
    at android.graphics.drawable.Drawable.createFromXml(Drawable.java:822)
    at android.content.res.Resources.loadDrawable(Resources.java:1950)
    ... 39 more

I am using HoloEverywhere which lets me reference the resources directly, but you should get a similar problem in the native case. I don't think the primary, non-selected, non-activated (etc.) color used as a component in the state list xml is exposed through an attribute.

In any case, the text color used is dependent on the theme that you, the app developer, chooses. If you choose to use the Holo (dark) theme then your text will be a light color, and the user won't be able to affect this. You don't need to make the your line color dynamic for your app.

Upvotes: 8

M-Wajeeh
M-Wajeeh

Reputation: 17284

I take it that you want to use native android primary text color.

<item name="android:background">@android:color/primary_text_dark</item>

Upvotes: 0

Related Questions