Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to obtain a theme by its reference id

I need to extract a default value from a theme, BUT NOT from the current theme.

I know that I can get get the attributes from the current theme like this:

TypedValue typedValue = new TypedValue();
Theme currentTheme = context.getTheme();
currentTheme.resolveAttribute(android.R.attr.windowBackground, typedValue, true);
// result is in: typedValue.data

but I need something like:

Theme darkTheme = getTheme(R.style.AppTheme.Dark);

... I only need to extract a single value, I do not want to change the current theme.

like image 739
Björn Kechel Avatar asked Feb 01 '17 10:02

Björn Kechel


1 Answers

There doesn't seem to be any direct way to instantiate or otherwise create Theme objects from resources, at least as far as I could find.

The initial suggestion was to create a temporary ContextThemeWrapper and get the Theme object from that. We wrap the application Context, since it won't (shouldn't) have a theme on it already:

Theme darkTheme = new ContextThemeWrapper(getApplicationContext(), R.style.AppTheme_Dark).getTheme();

Then I realized we could do something like:

Theme darkTheme = getResources().newTheme();
darkTheme.applyStyle(R.style.AppTheme_Dark, true);

It turns out that this is exactly what the ContextThemeWrapper solution is doing internally anyway, so this method is obviously preferable, as we're not needlessly creating and discarding a ContextThemeWrapper instance.

Note that it doesn't really matter on which Context the getResources() call is made; ultimately newTheme() just returns an empty Theme. Also, despite the name (and the general non-interchangeability of styles and themes), Theme#applyStyle() actually does take a theme resource ID.

like image 187
Mike M. Avatar answered Oct 15 '22 06:10

Mike M.