11

I want to create two themes, GrayTheme and RedTheme, that modify one style attribute. For example here are my two themes, default font color is white, which is fine for both themes:

<style name="RedTheme" parent="@style/Theme.AppCompat.Light.DarkActionBar">
    <item name="android:textColor">@color/white</item>
</style>

<style name="GrayTheme" parent="@style/Theme.AppCompat.Light.DarkActionBar">
    <item name="android:textColor">@color/white</item>
</style>

But I have a style that I use for Header TextViews. If I am using the RedTheme I want the style HeaderFont to have textColor red and if it is the GrayTheme I want the HeaderFont textColor to be gray, without me having to modify the individual xml files that access this HeaderFont style.

<style name="HeaderFont" parent="@android:style/TextAppearance.Medium">
    <item name="android:textColor">@color/gray</item>
</style>

I've been searching around looking for a graceful solution to this, but haven't been able to find anything. Ideas?

2 Answers 2

29

After many failures of finding a clean solution I finally found an answer that works beautifully.

I created a custom attribute headerFontColor and added it to /res/values/attrs.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <attr name="headerFontColor" format="reference|color" />
</resources>

Next, in the style for HeaderFont I added updated the textColor to be the new custom attribute (headerFontColor) instead of a specific color

<style name="HeaderFont" parent="@android:style/TextAppearance.Medium">
    <item name="android:textColor">?headerFontColor</item>
</style>

Now, I can simply set the headerFontColor attribute based on the theme

<style name="RedTheme" parent="@style/Theme.AppCompat.Light.DarkActionBar">
    <item name="android:textColor">@color/white</item>
    <item name="headerFontColor">@color/red</item>
</style>
<style name="GrayTheme" parent="@style/Theme.AppCompat.Light.DarkActionBar">
    <item name="android:textColor">@color/white</item>
    <item name="headerFontColor">@color/gray</item>
</style>

After doing this, all TextViews that use the HeaderFont style get updated with the headerFontColor just by switching the Theme

This solution guided me: Setting a color based on theme

Sign up to request clarification or add additional context in comments.

3 Comments

What file did you put the custom attribute in?
I made an attributes file in the values directory /res/values/attrs.xml @KennethWorden
This works flawlessly and opened new doors for custom color choice based on dark/night modes. Thank you so much!
0

I used references from google's iosched project.

Created an attrs.xml file in res/values/

<?xml version="1.0" encoding="utf-8"?>
<resources>
  <declare-styleable name="Theme">
    <attr name="headerFontColor" format="color" />
  </declare-styleable>
</resources>

Then in themes.xml

<style name="RedTheme" parent="@style/Theme.AppCompat.Light.DarkActionBar">
  <item name="headerFontColor">@color/red</item>
</style>

<style name="GrayTheme" parent="@style/Theme.AppCompat.Light.DarkActionBar">
  <item name="headerFontColor">@color/gray</item>
</style>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.