Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android - reference the value of an attribute in the currently-applied theme from code

Tags:

android

the Android devGuide explains how it is possible to reference the value of an attribute in the currently-applied theme, using the question-mark (?) instead of at (@).

Does anyone know how to do this from code, e.g. in a customized component?

like image 542
Julian Arz Avatar asked Jun 21 '10 09:06

Julian Arz


People also ask

What does ATTR mean in Android?

The Attr interface represents an attribute in an Element object. Typically the allowable values for the attribute are defined in a schema associated with the document.

What is attr in XML Android?

This allows you to define attributes a custom view can use. You do this by specifying an <attr> element, if it was previously defined you do not specify the format . If you wish to reuse an android attr, for example, android:gravity, then you can do that in the name , as follows.


2 Answers

In XML, it would look something like this:

style="?header_background"

programmatically, it's a little trickier. In your activity:

private static Theme theme = null;

protected void onCreate(Bundle savedInstanceState) {
   ...
   theme = getTheme();
   ...
}

public static int getThemeColors(int attr){
   TypedValue typedvalueattr = new TypedValue();
   theme.resolveAttribute(attr, typedvalueattr, true);
   return typedvalueattr.resourceId;
}

And when you want to access an attribute of the theme, you would do something like this:

int outside_background = MyActivity.getThemeColors(R.attr.outside_background);
setBackgroundColor(getResources().getColor(outside_background));

It's a little more convoluted, but there you go ;-)

like image 185
atraudes Avatar answered Oct 12 '22 23:10

atraudes


The above is not a good way of doing this for many reasons. NullPointerExceptions is one.

Below is the correct way of doing this.

public final class ThemeUtils {
    // Prevent instantiation since this is a utility class
    private ThemeUtils() {}

   /**
    * Returns the color value of the style attribute queried.
    *
    * <p>The attribute will be queried from the theme returned from {@link Context#getTheme()}.</p>
    *
    * @param context the caller's context
    * @param attribResId the attribute id (i.e. R.attr.some_attribute)
    * @param defaultValue the value to return if the attribute does not exist
    * @return the color value for the attribute or defaultValue
    */
    public static int getStyleAttribColorValue(final Context context, final int attribResId, final int defaultValue) {
        final TypedValue tv = new TypedValue();
        final boolean found = context.getTheme().resolveAttribute(attribResId, tv, true);
        return found ? tv.data : defaultValue;
    }
}

Then to use just do:

final int attribColor = ThemeUtils.getStyleAttribColorValue(context, R.attr.some_attr, 0x000000 /* default color */);

Just make sure the context that you pass in came from the Activity. Don't do getApplicationContext() or the theme returned will be from the Application object and not the Activity.

like image 21
Daniel Ochoa Avatar answered Oct 13 '22 01:10

Daniel Ochoa