6

I am using custom attributes to implement theme switching in my application. I have the following attribute defined:

<resources>
    <attr name="TextAppearance_Footer" format="reference"></attr>
</resources>

I have two themes which define this attribute differently:

<style name="NI_AppTheme.Dark">
    <item name="TextAppearance_Footer">@style/Footer</item>
</style>

The @style/Footer is defined as follows:

<style name="Footer" parent="@android:style/TextAppearance.Large">
    <item name="android:textColor">#00FF00</item> // Green
</style>

Now if I try to set this style to a TextView using:

textView.setTextAppearance(this, R.attr.TextAppearance_Footer);

It does not work (i.e. does not set the text to Green). However, if I specify the text appearance via xml using:

android:textAppearance="?TextAppearance_Footer"

It works fine. What could I be missing? I need to set the attributes because I want to dynamically be able to switch between themes.

Additional Info:

If I use:

textView.setTextAppearance(this, R.style.NI_AppTheme.Dark);

It seems to work all right.

EDIT: Tested Working Solution (thanks @nininho):

Resources.Theme theme = getTheme();
TypedValue styleID = new TypedValue();
if (theme.resolveAttribute(R.attr.Channel_Title_Style, styleID, true)) {
     channelTitle.setTextAppearance(this, styleID.data);
}
Code Poet
  • 11,227
  • 19
  • 64
  • 97

1 Answers1

12

Why not use:

textView.setTextAppearance(this, R.style.Footer);

I think that the textAppearance must be a style.

Edit:

Maybe you should try this:

TypedArray a = context.obtainStyledAttributes(attrs,
new int[] { R.attr.TextAppearance_Footer });

int id = a.getResourceId(R.attr.TextAppearance_Footer, defValue);
textView.setTextAppearance(this, id);

EDIT: Correct Tested Code:

Resources.Theme theme = getTheme();
TypedValue styleID = new TypedValue();
if (theme.resolveAttribute(R.attr.Channel_Title_Style, styleID, true)) {
     channelTitle.setTextAppearance(this, styleID.data);
}
Code Poet
  • 11,227
  • 19
  • 64
  • 97
Marcio Covre
  • 4,556
  • 2
  • 22
  • 24
  • Because probably he wants to have this selected through the theme, and not using R.style.Footer directly. – aromero Jan 06 '12 at 12:46
  • So he should use the theme, but from the question he doesn't want to use it (don't know why) – Marcio Covre Jan 06 '12 at 12:56
  • Not sure that's the case. What's he is trying to do is delegate the TextAppearance style to the theme. TextAppearance_Footer is the attribute that does the linking, so for example, let's say you have theme1 and theme2. theme1 will say TextAppearance_Footer => textAppearance1 and theme2 will say TextAppearance_Footer => textAppearance2. In your widgets you just say textAppearance => TextAppearance_Footer. What you get is an automatic style linking based on the current theme – aromero Jan 06 '12 at 13:03
  • Ok, so he would use the theme on the apps manifest and not use on the code here. So for this to work he shouldn't be passing the attr id, but get the style id from the attr and pass to setTextAppearance. – Marcio Covre Jan 06 '12 at 13:18
  • @aromero guessed it right as far as why is concerned. I want to switch the textview style automatically using the currently selected theme set for the application using the `application:theme` tag or `setTheme`. – Code Poet Jan 06 '12 at 13:36
  • @nininho can you please give code example of how to do it? I'm not sure of what you're suggesting. – Code Poet Jan 06 '12 at 13:53
  • @nininho Awesome! Thanks for making me think in a direction that I did not know existed. The correct working code, however, is slightly different. I give full credit to you though. – Code Poet Jan 06 '12 at 16:26