Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android themes trouble implementing the simplest: custom per theme color

I'm a beginner in Android development and, although coding makes perfect sence, android themes IMHO don't

I have trouble implementing this simple task:

I have (for example) a color named "blah"

<?xml version="1.0" encoding="utf-8"?>
<resources>
  <color name="blah">#F0F0F0</color>
<resources>

which is used everywhere in XML layouts or code and by different view complonents as "@color/blah"

I would simply like to make this color value change per-theme

So when i use MyTheme1, blah should be #F0F0F0 and when i use MyTheme2 blah should be #00FF00

I've been reading about themes and still cant find out how to implement this simple task, since my app does not require special styles and so on, just per-theme colors.

Thanx in advance

UPDATE:

After the link provided by Mohamed_AbdAllah, i successfully managed to create some custom colors by defining them in attrs.xml and styles.xml:

attrs.xml

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

styles.xml

<style name="AppBaseThemeDark" parent="android:Theme.Black">
<item name="color_item_title">@color/White</item>                      
</style>

But now a much more serious problem arises

I can successfully use the color ?color_item_title in every view, so buttons and text actually gets that color.

But using that ?color_item_title on custom drawables or listview layouts (THAT IS VIEWS THAT GET INFLATED DURING RUNTIME) causes a crash.

So using ?color_item_title inside a listview listitem layout crashes at runtime with an inflater message at that line :(

It also crashes at my drawables: (Inflation error again)

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >

<solid android:color="@color/Black" />
<corners
    android:bottomLeftRadius="8dp"
    android:bottomRightRadius="8dp"
    android:topLeftRadius="8dp"
    android:topRightRadius="8dp" />
 <stroke android:width="1dp" android:color="?color_item_title" />
</shape>
like image 876
John S Avatar asked May 19 '13 10:05

John S


1 Answers

After searching and trying, I got the tip that there are some things you can do and some things you cant.

You can

a) Define your own attributes in attrs

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

b) Set their values in your styles.xml

<style name="AppBaseThemeDark" parent="android:Theme.Black">
           <item name="color_gallery_backround">@color/White</item>              
 </style>
 <style name="AppBaseThemeWhite" parent="android:Theme.Light">
           <item name="color_gallery_backround">@color/Black</item>              
 </style>

c) Use them in any view as ?color_gallery_backround or ?attr/color_gallery_backround for example

android:background="?attr/color_gallery_backround"

YOU CANT

a) You cant access this attribute from custom drawables, as they are not valid during inflation

so you cant use ?attr/color_gallery_backround in here:

customshape.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >

<solid android:color="**?attr/color_gallery_backround**" />
 <stroke android:width="2dp" android:color="@color/Black" />
</shape>

b) You cant access this attribute in a view that will get inflated during (for example) a ListView as a ListItem view

So theme "support" for attributes at least up to API 10 has depth limits.

Solutions

As suggested, you have to create TWO separate drawables using different colors and set up attributes to reference these drawables according to theme:

attrs.xml

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

and on each theme, setup which actual drawable to use in styles.xml:

<resources>

    <style name="AppBaseThemeDark" parent="android:Theme.Black">
           <item name="rounded_background">@drawable/round_rect_shape_dark</item>    
           </style>

    <style name="AppBaseThemeLight" parent="android:Theme.Light">
           <item name="rounded_background">@drawable/round_rect_shape_white</item>     
           </style>

</resources>

Now you can reference your drawable as ?rounded_background and let the theme choose it.

For inflated views inside ListView listitem layouts, you have to programmatically set colors.

like image 88
John S Avatar answered Sep 27 '22 21:09

John S