understand styles and themes

theme guide


<TextView    
  style="@style/CodeFont"    
  android:text="@string/hello" />

<resources>    
<style name="CodeFont" parent="@android:style/TextAppearance.Medium">        
  <item name="android:layout_width">fill_parent</item>        
  <item name="android:layout_height">wrap_content</item>        
  <item name="android:textColor">#00FF00</item>        
  <item name="android:typeface">monospace</item>    
</style>
</resources>

view,
activity,
or an application

<style name="CodeFont.Red">        
  <item name="android:textColor">#FF0000</item>    
</style>

This technique for inheritance by chaining together names only works for styles defined by your own resources. You can't inherit Android built-in styles this way. To reference a built-in style, such as TextAppearance, you must use the parent attribute.

The best place to find properties that apply to a specific View is the corresponding class reference

All style properties are available in R.attr

Note that this is a large web page. It may take a minute to load on a fast connection.

if you apply a style to a View that does not support all of the style properties, the View will apply only those properties that are supported and simply ignore the others.

Some style properties, however, are not supported by any View element and can only be applied as a theme. These style properties apply to the entire window and not to any type of View. For example, style properties for a theme can hide the application title, hide the status bar, or change the window's background. These kind of style properties do not belong to any View object. To discover these theme-only style properties, look at the R.attr reference for attributes that begin with window. For instance, windowNoTitle and windowBackground are style properties that are effective only when the style is applied as a theme to an Activity or application. See the next section for information about applying a style as a theme.

If a style is applied to a ViewGroup, the child View elements will not inherit the style properties


<application android:theme="@style/CustomTheme">
or
<activity android:theme="@android:style/Theme.Dialog">

<color name="custom_theme_color">#b0b0ff</color>

<style name="CustomTheme" parent="android:Theme.Light">    

  <item name="android:windowBackground">@color/custom_theme_color</item> 
  <item name="android:colorBackground">@color/custom_theme_color</item>
</style>

When applied to an activity or application it becomes a theme. is that right??

R.styleable.theme

Here is a clue to find out what themes are available

Because themes are essentially resources of type "style" you should be able to look up docs for R.style and discover what is supported.

To use the styles listed here, replace all underscores in the style name with a period. For example, you can apply the Theme_NoTitleBar theme with "@android:style/Theme.NoTitleBar".

In what XML file are android styles defined: styles.xml

This is a direct link to the android source code. You can use this pattern to your advantage to look up source code for other files as well.

Apparently there is a themes.xml as well

See a local copy here as the android git location has changed.

looks like the GIT links need some kind of a password to get in. I will post later if I can find a way to get to these files.

I do have them on my local drive as I used "git" to download them. I will try to post a link to online soon.


R.attr
R.style
R.styleable

A collection of named attributes that can be applied to a view, activity, application element. this is how you reuse xml based attributes for different views.

How? instead of indicating color, font, background on every view, your views could say "Hey! just use the evening style" which has certain complementing colors.

So, what is the difference between a style and a styleable?

Search for: So, what is the difference between a style and a styleable?

A style is a collection of [attribute] values

A styleable is a collection of attribute names!!

Well, there is an array in Android's bowels in a file, possibly called, attrs.xml. In this file there is an array of attribute names collected under a namespace called "Theme". The attribute names are also described here as to what their type is. whether each attribute is a string or an int or an enumeration or a reference etc.

A theme is essentially a 'name' for a particular style

BaseTheme.SubTheme.SubberTheme.SubbestTheme :)

You can checkout the themes that are defined in android: R.style namepace

what is the difference between R.style.Theme and R.styleable.Theme

The former R.style.Theme is a base theme that defines values for all of the properties. R.styleable.Theme is just a list of attributes that could be themed.

quite likely, if one wants to know what attributes are set by R.style.theme, you can look them up using R.styleable.Theme namespace.

Because this is a catalogue of all the attributes, all the components of Android may look for in their xml definitions, one could quickly look at the expected XML attributes and their types.

you can possible get to the same (close) information by looking at their corresponding class definitions.

What is the difference between CSS like styling and Android styling?

Search for: What is the difference between CSS like styling and Android styling?


<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2007 The Android Open Source Project

     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at
  
          http://www.apache.org/licenses/LICENSE-2.0
  
     Unless required by applicable law or agreed to in writing, software
     distributed under the License is distributed on an "AS IS" BASIS,
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     See the License for the specific language governing permissions and
     limitations under the License.
-->

<resources>
    <!-- A custom theme that is a variation on the light them with a different
         background color. -->
    <color name="custom_theme_color">#b0b0ff</color>
    <style name="CustomTheme" parent="android:Theme.Light">
        <item name="android:windowBackground">@color/custom_theme_color</item>
        <item name="android:colorBackground">@color/custom_theme_color</item>
    </style>

    <!-- This is a theme that will adjust itself depending on the API version.
         The default definition is the safe one, using a theme that has always
         been defined.  Look at values-11/styles.xml for a variation that is
         selected when the holographic theme is available. -->
    <style name="ThemeHolo" parent="android:Theme">
    </style>

    <!-- Base application theme is the default theme. -->
    <style name="Theme" parent="android:Theme">
    </style>

    <!-- Base application theme is the default theme. -->
    <style name="BadTheme" parent="@android:style/Theme.Holo.Light.NoActionBar">
    </style>

    <!-- Variation on our application theme that forces a plain
        text style. -->
    <style name="Theme.PlainText">
        <item name="android:textAppearance">@style/TextAppearance.Theme.PlainText</item>
    </style>

    <!-- Variation on our application theme that has a black
         background. -->
    <style name="Theme.Black">
        <item name="android:windowBackground">@drawable/screen_background_black</item>
    </style>

    <!-- A theme for a custom dialog appearance.  Here we use an ugly
         custom frame. -->
    <style name="Theme.CustomDialog" parent="android:style/Theme.Dialog">
        <item name="android:windowBackground">@drawable/filled_box</item>
    </style>

    <!-- A theme that has a wallpaper background.  Here we explicitly specify
         that this theme is to inherit from the system's wallpaper theme,
         which sets up various attributes correctly. -->
    <style name="Theme.Wallpaper" parent="android:style/Theme.Wallpaper">
        <item name="android:colorForeground">#fff</item>
    </style>

    <!-- A theme that has a translucent background.  Here we explicitly specify
         that this theme is to inherit from the system's translucent theme,
         which sets up various attributes correctly. -->
    <style name="Theme.Translucent" parent="android:style/Theme.Translucent">
        <item name="android:windowBackground">@drawable/translucent_background</item>
        <item name="android:windowNoTitle">true</item>
        <item name="android:colorForeground">#fff</item>
    </style>

    <!-- Variation on our application theme that has a transparent
         background; this example completely removes the background,
         allowing the activity to decide how to composite.  Also here we
         force the translucency ourself rather than making use of the built-in
         translucent theme. -->
    <style name="Theme.Transparent">
        <item name="android:windowIsTranslucent">true</item>
        <item name="android:windowAnimationStyle">@android:style/Animation.Translucent</item>
        <item name="android:windowBackground">@drawable/transparent_background</item>
        <item name="android:windowNoTitle">true</item>
        <item name="android:colorForeground">#fff</item>
    </style>
    
    <!-- Older platforms don't have Theme.Holo.DialogWhenLarge; we will define
         our own wrapper theme that uses it only when running on the appropriate
         platform version.  On older platforms, we always use the generic
         fullscreen theme, because they don't support some feature that help
         in correctly laying out an activity as a dialog. -->
    <style name="ThemeDialogWhenLarge" parent="android:style/Theme">
    </style>

    <style name="TextAppearance.Theme.PlainText" parent="android:TextAppearance.Theme">
        <item name="android:textStyle">normal</item>
    </style>

    <style name="ImageView120dpi">
        <item name="android:src">@drawable/stylogo120dpi</item>
        <item name="android:layout_width">wrap_content</item>
        <item name="android:layout_height">wrap_content</item>
    </style>

    <style name="ImageView160dpi">
        <item name="android:src">@drawable/stylogo160dpi</item>
        <item name="android:layout_width">wrap_content</item>
        <item name="android:layout_height">wrap_content</item>
    </style>

    <style name="ImageView240dpi">
        <item name="android:src">@drawable/stylogo240dpi</item>
        <item name="android:layout_width">wrap_content</item>
        <item name="android:layout_height">wrap_content</item>
    </style>
</resources>

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <!-- These are the attributes that we want to retrieve from the theme
         in app/PreferencesFromCode.java -->
    <declare-styleable name="TogglePrefAttrs">
        <attr name="android:preferenceLayoutChild" />
    </declare-styleable>
    
    <!-- These are the attributes that we want to retrieve from the theme
         in view/Gallery1.java -->
    <declare-styleable name="Gallery1">
        <attr name="android:galleryItemBackground" />
    </declare-styleable>
    
     <declare-styleable name="LabelView">
        <attr name="text" format="string" />
        <attr name="textColor" format="color" />
        <attr name="textSize" format="dimension" />
    </declare-styleable>

    <!-- These are attributes used with 'DraggableDot' drawables in
         view/DragAndDropActivity.java and view/DraggableDot.java -->
    <declare-styleable name="DraggableDot">
        <attr name="radius" format="dimension" />
        <attr name="legend" format="string" />
        <attr name="anr">
            <enum name="none" value="0" />
            <enum name="thumbnail" value="1" />
            <enum name="drop" value="2" />
        </attr>
    </declare-styleable>

    <!-- These are the attributes that we want to retrieve for
         app/FragmentArguments.java -->

    <declare-styleable name="FragmentArguments">
        <attr name="android:label" />
    </declare-styleable>

</resources>

The declare-styleable turns into R.styleable namespace

Understand styleables and R.styleable name space


styles are defined in styles.xml
general attributes are defined in attrs.xml
styleables are also defined in attrs.xml

well themes are styles. so look in styles.xml

<EditText id="text"    
  android:layout_width="fill_parent"    
  android:layout_height="wrap_content"    
  android:textColor="?android:textColorSecondary"
  android:text="@string/hello_world" />

The "?" is used to say pick the value from the current theme that is in use.


<activity android:name=".app.DialogActivity"
                android:label="@string/activity_dialog"
                android:theme="@android:style/Theme.Holo.Dialog">

The style for this dialog is coming from android package.


<activity android:name=".app.CustomDialogActivity"
                android:label="@string/activity_custom_dialog"
                android:theme="@style/Theme.CustomDialog">

<!-- Base application theme is the default theme. -->
    <style name="Theme" parent="android:Theme">
    </style>

Look at the styles.xml above for a quick reference

How is R.styleable.Theme used?

Search for: How is R.styleable.Theme used?


TypedArray
a = getContext().obtainStyledAttributes(android.R.styleable.Theme);

mSecondaryTextColor = a.getColorStateList(android.R.styleable.Theme_textColorSecondary);

a.recycle();

void setStyle(Context context) {
    TypedArray a = context.obtainStyledAttributes(com.android.internal.R.styleable.Theme);
    background = a.getResourceId(
            com.android.internal.R.styleable.Theme_panelBackground, 0);
    fullBackground = a.getResourceId(
            com.android.internal.R.styleable.Theme_panelFullBackground, 0);
    windowAnimations = a.getResourceId(
            com.android.internal.R.styleable.Theme_windowAnimationStyle, 0);
    isCompact = a.getBoolean(
            com.android.internal.R.styleable.Theme_panelMenuIsCompact, false);
    listPresenterTheme = a.getResourceId(
            com.android.internal.R.styleable.Theme_panelMenuListTheme,
            com.android.internal.R.style.Theme_ExpandedMenu);
    a.recycle();
}

Take a look at the /res/values/themes.xml again


<!-- The default system theme. This is the theme used for activities
         that have not explicitly set their own theme.
         
         <p>You can count on this being a dark
         background with light text on top, but should try to make no
         other assumptions about its appearance. In particular, the text
         inside of widgets using this theme may be completely different,
         with the widget container being a light color and the text on top
         of it a dark color.
    -->

themes_device_defaults.xml

Search for: themes_device_defaults.xml

This file contains the themes that are the Device Defaults. If you want to edit themes to skin your device, do it here. We recommend that you do not edit themes.xml and instead edit this file.

Editing this file instead of themes.xml will greatly simplify merges for future platform versions and CTS compliance will be easier.

New Honeycomb holographic theme. Dark version. The widgets in the holographic theme are translucent on their brackground, so applications must ensure that any background they use with this theme is itself dark; otherwise, it will be difficult to see the widgets. The new UI style also includes a full action bar by default.

Styles used by the Holo theme are named using the convention Type.Holo.Etc. (For example, Widget.Holo.Button, TextAppearance.Holo.Widget.PopupMenu.Large.) Specific resources used by Holo are named using the convention @type/foo_bar_baz_holo with trailing _dark or _light specifiers if they are not shared between both light and dark versions of the theme.


<style name="Theme.Holo">
        <item name="colorForeground">@android:color/bright_foreground_holo_dark</item>
        <item name="colorForegroundInverse">@android:color/bright_foreground_inverse_holo_dark</item>

If themes are in themes.xml what is in styles.xml??

It appears that styles.xml defines modular styles that are reused by themes.xml.

The Holo themes must not be modified in order to pass CTS. Many related themes and styles depend on other values defined in this file. If you would like to provide custom themes and styles for your device, please see styles_device_defaults.xml.

So you have: styles_device_defaults.xml as well


themes.xml
themes_device_defaults.xml
styles.xml
styles_device_defaults.xml

In /core/res/values/attrs.xml

Although a style gathers many attributes together, there is no styleable declared at each style level!! instead there is a single styleable that aggregates all names for style attributes. It is called


R.styleable.Theme

You can see this definition in /core/res/values/attrs.xml

You can access the relevant files here

I have copied the following files from the android 4.0 source distribution for quick reference.

styles.xml
themes.xml
device default styles.xml
device default themes.xml

working with android theme

Search for: working with android theme

Here is a nice article from androidengineer.com


<style name="MyTheme" parent="android:Theme">
  <item name="android:some-attribute-name" value="some-value"/>
  <item name="MyCustomAttribute" value="some-value"/>
</style>

A style is a collection of attributes. The attributes may belong to all kinds of views or other components. Example is a text view, or a list view or a window for that matter.

So in sense a style is a pretty open ended collection of attributes, as long as they are attributes.

This "requirement" forces you to define your custom attributes in your attrs.xml to start with.

Usually a custom attribute or attributes are defined so that you can use them to alter the behavior of your own custom views. So if you don't have a custom view why do you ever need to define a custom attribute?

what component will recognize it??


<attr name="MyColor" format="color"/>
<style name="mystyle">
   <item name="MyColor" value="@color/red"/>
</style>

<TextView
   android:color="?MyColor"/>

This is a pattern where we give a symbolic name for a value and reuse that name in a number of places through the "?" format

before setting the view.

A theme applied to your application or activity cascades but not the one applied to a viewgroup

1. Objects have attributes (ex: TextView)

2. You can declare attributes for an object in xml files (ex: layouts)

3. attributes need to be declared through "attr" tag in the values sub directory.

4. attributes are usually declared in /res/values/attrs.xml

5. an attribute definition has a name and a format (like boolean, string etc)

6. Attribute formats can be combined (Ex: reference|color)

7. A style is a collection of an arbitrary set of attributes that may pertain to more than on type of object.

8. A style contains values for set of attributes

9. A style has a name

10. An object can subscribe to a style using its name and a special object attribute called "style" (ex: style="@style/mystyle")

11. Many objects can subscribe to the same style

12. When an activity or an application subscribe to a style it is called a theme.

13. A style applied to a view group doesn't descend the hieararchy

14. A style applied to an activity does descend to the views that the activity holds. Same is true when that theme is applied to the application as a whole.

15. A style is defined through a value tag called "style"

16. Styles are usually defined in /res/values/styles.xml

17. When you intend to apply styles at an activity or application level, then one can use /res/values/themes.xml instead.

18. A style can have a parent theme.

19. A parent theme (when it is an android parent theme) is indicated through a "parent" attribute on a style element

20. A parent theme in your own package uses a dot structure to indicate parentage (ex: BaseTheme.SpecialTheme)

21. You should start your own theme by first inheriting the base android theme

22. You should see a copy of android themes.xml and styles.xml to know how to specialize the portions that you need

23. If you define your own custom attributes for custom objects you can include them in your specialized theme

25. You can dynamically set a theme for your activity in the oncreate callback prior to setting the view for that activity

26. It is entirely possible to define an attribute and specify a value for it (in a style spec) and refer to that value by its attribute name using a "?" mark.

27. The value of an attribute can use a "?" to de-reference another value's attribute (ex: attrib1="?attrib2" Use the value of attrib2 as the value of attrib1)

28. while a style is a collection of attribute values, a styleable is a collection of attribute names/definitions/types. Styleables are defined in attrs.xml as they are closely related to attributes.

29. Styleables don't play a big role in XML definitions

30. Styleables are useful in Java code and used by objects to read a set of attributes that those objects care about

31. TypedArray is used in conjunction with styleables to read a set of attributes pertaining to a custom component

32. Context.obtainStyledAttribues() is used in conjunction with TypedArray and styleables

33. Attributes are represented by R.attr.*

34. Styles and themes are represented by R.style.*

35. Styleable grouping are represented by R.styleable.* and R.styleable.group_attribute1, R.styleable.group_attribute2 etc.

36. The keys files to understand styles are attrs.xml, styles.xml, and possibly themes.xml if present.

textAppearance is defined in styles.xml


All valid Attributes are defined in attrs.xml
  this is the total domain of attributes
A style is a collection of attribute values
  values can come from values.xml
  value for an attribute can be another style
  so a value of one attribute can be a collection of attribute values
A theme is just a style with a LOT more collection of related attributes

Theme (original android)
  dark
  light
Holo (Honeycomb)
  dark
  light

Theme
Theme.light
Theme.Holo
Theme.Holo.light

Holo is not available on 2.3 or below

See the link on top right of this page.

using the same technique of resource swapping

When applying styles that only modify a View?s text properties the style is applied via the Text Appearance property (XML attribute android:textAppearance). Styles that modify non-text properties are applied via the style property.

This is taken from the link here

Your best bet to know what are the attributes a theme defines see the attrs.xml

textColorTertiary

Search for: textColorTertiary

Read Theme.java to understand the order of getting attributes

Any attribute values in the given AttributeSet.

The style resource specified in the AttributeSet (named "style").

The default style specified by defStyleAttr and defStyleRes

The base values in this theme.

Each of these inputs is considered in-order, with the first listed taking precedence over the following ones.

Are there any attributes in base attrs.xml that are outside any styleables?


there are a whole bunch of attributes that are under theme.
Although theme is a styleable it doesnt belong to any one component.
There are things like
  textSize
  textColor
etc that are outside of all styleables
Then you have custom objects like
  window
  alertdialog 
  etc.

View
...its inherited clases such as
AbsListView
TextView
etc..

The implication may be, the ADT tool can looking at the type hierarchy locate the total set of allowed attributes for a given control in the layout files!!! May be.

Question mark (?) in XML attributes for Android

Search for: Question mark (?) in XML attributes for Android

At SOF

This is the link I am looking for from android dev guide


<declare-styleable name="TextView">
    <attr name="bufferType">
      <enum name="normal" value="0"/>
      <enum name="spannable" value="1"/>
      <enum name="editable" value="2"/>
    </attr>
    <attr name="text" format="string" localization="suggested"/>
    <attr name="hint" format="string"/>
    <attr name="textColor"/>
    <attr name="textColorHighlight"/>
    <attr name="textColorHint"/>
    <attr name="textAppearance"/>
    <attr name="textSize"/>
    <attr name="textScaleX" format="float"/>
...
</declare-styleable>

Notice how this styleable reuses number of common attributes such as textColor, textSize etc while newly defining things like textScaleX

meaning they exist in the attrs.xml file outside of any styleable definition including the theme.

this file is the total of all the possible attributes and their formats. It does not contain values. The values are provided in the values sub directory as style xml node.


Attribtutes that are grouped for each component: like Button, CheckBox etc.
Attributes that are grouped under a styleable called Theme
Attribtues that are open and global and have no grouping at all

textSize
textColor
etc.

<declare-styleable name="TextView">
    <attr name="bufferType">
      <enum name="normal" value="0"/>
      <enum name="spannable" value="1"/>
      <enum name="editable" value="2"/>
    </attr>
    <attr name="text" format="string" localization="suggested"/>
    <attr name="hint" format="string"/>
    <attr name="textColor"/>
    <attr name="textColorHighlight"/>
    <attr name="textColorHint"/>
    <attr name="textAppearance"/>
    <attr name="textSize"/>
    <attr name="textScaleX" format="float"/>
...
</declare-styleable>

Singular Attributes pointing to singular values
  (like textPrimaryColor, textSecondaryColor)
Multi-valued attributes pointing to other styles
  (like buttonStyle, checkBoxStyle etc)

<declare-styleable name="Theme">
   <attr name="colorForeground" format="color"/>
   <attr name="colorForegroundInverse" format="color"/>

Values for these attributes are given in the themes.xml under a style named "Theme".

These attributes will use other resources like @android:color resources.

I was thinking that because "Theme" is styleable somewhere in the source code some class is going to be reading these values. But this happens rarely.

then who consumes values for these attributes?

as it turns out these are referenced by the multi-valued style resources used by various custom components like those derived from view or window etc.

So themes.xml gives these values. Then those values are referenced in the styles for various components. Then those components end up using these singular values indirectly through their style specifications.

yes. it is round about.

Multi-valued (or styled) theme attributes are a bit spinny

Clearly this declaration is outside of the "theme" styleable. However the default style to be used by TextView is most likely declared inside the theme as a single attribute.

we will see in a minute. I don't this for sure but I believe it is!


<attr name="spinnerStyle" format="reference"/>
<!--  Default dropdown Spinner style.  -->
<attr name="dropDownSpinnerStyle" format="reference"/>
<!--  Default ActionBar dropdown style.  -->
<attr name="actionDropDownStyle" format="reference"/>
<!--  Default action button style.  -->
<attr name="actionButtonStyle" format="reference"/>
<!--  Default Star style.  -->
<attr name="starStyle" format="reference"/>
<!--  Default TabWidget style.  -->
<attr name="tabWidgetStyle" format="reference"/>
<!--  Default TextView style.  -->
<attr name="textViewStyle" format="reference"/>
<!--  Default WebTextView style.  -->
<attr name="webTextViewStyle" format="reference"/>
<!--  Default WebView style.  -->
<attr name="webViewStyle" format="reference"/>
<!--  Default style for drop down items.  -->
<attr name="dropDownItemStyle" format="reference"/>
<!--  Default style for spinner drop down items.  -->
<attr name="spinnerDropDownItemStyle" format="reference"/>
<!--  Default style for drop down hints.  -->
<attr name="dropDownHintAppearance" format="reference"/>
<!--  Default spinner item style.  -->

<!--  Default TextView style.  -->
<attr name="textViewStyle" format="reference"/>

a custom object declares its attributes through styleable
the default style name is also an attribute and typically part of theme
the default style name is given a value by the theme.xml
the value given by the theme.xml is a style which is in style.xml
the values in the style.xml for the default style will use attributes
  from the styleable for that component. the values will be borrowed
  from the single attribute values defined by theme.xml

how are singly valued attributes in the theme are utilized.

how the default style names of custom objects are names in the theme and how they indirectly point to the single values (or not and directly hard coded) of the theme or the global attributes outside.

Of course you can override and specialize these configuration files based on device and environment and a whole host of things.

other than that they are like apache config files that control its behavior.

but it may take sometime to understand the connection between these configuration files and custom controls.

Although one might think of these as CSS files I seem to draw more parallels to configuration files!!

but again when I know more I might think otherwise.

I am hoping to draw a better visualization picture of this and I will soon