How to Get Background Color from Current Theme Programmatically

how to get background color from current theme programmatically

You can get the background color (or Drawable) from the current theme by:

TypedValue a = new TypedValue();
getTheme().resolveAttribute(android.R.attr.windowBackground, a, true);
if (a.isColorType()) {
// windowBackground is a color
int color = a.data;
} else {
// windowBackground is not a color, probably a drawable
Drawable d = activity.getResources().getDrawable(a.resourceId);
}

isColorType was introduced in API level 29. Before then, you can use the following instead:

if (a.type >= TypedValue.TYPE_FIRST_COLOR_INT && a.type <= TypedValue.TYPE_LAST_COLOR_INT)

Programmatically get theme colors

You can look at the source from android's themes.xml, styles.xml, and colors.xml. The one thing you notice from the colors.xml is that there isn't very many colors defined. This is because most of the widgets are done via 9-patch files.

Button style:

 223     <style name="Widget.Button">
224 <item name="android:background">@android:drawable/btn_default</item>
225 <item name="android:focusable">true</item>
226 <item name="android:clickable">true</item>
227 <item name="android:textAppearance">?android:attr/textAppearanceSmallInverse</item>
228 <item name="android:textColor">@android:color/primary_text_light</item>
229 <item name="android:gravity">center_vertical|center_horizontal</item>
230 </style>

All of the work done to change the background colors is done in the btn_default Drawable.

Source of btn_default.xml:

  17 <selector xmlns:android="http://schemas.android.com/apk/res/android">
18 <item android:state_window_focused="false" android:state_enabled="true"
19 android:drawable="@drawable/btn_default_normal" />
20 <item android:state_window_focused="false" android:state_enabled="false"
21 android:drawable="@drawable/btn_default_normal_disable" />
22 <item android:state_pressed="true"
23 android:drawable="@drawable/btn_default_pressed" />
24 <item android:state_focused="true" android:state_enabled="true"
25 android:drawable="@drawable/btn_default_selected" />
26 <item android:state_enabled="true"
27 android:drawable="@drawable/btn_default_normal" />
28 <item android:state_focused="true"
29 android:drawable="@drawable/btn_default_normal_disable_focused" />
30 <item
31 android:drawable="@drawable/btn_default_normal_disable" />
32 </selector>

Each one of those is a 9-patch file. The problem is that those are pngs. The colors are built into the image files and are not defined anywhere. As you've noticed these images can be replaced and the look changes.

Unfortunately, what you want is not possible. You are going to have to choose a single color to go with. This color probably should be chosen to fit with the rest of your application. Sorry :(

How to get a color from the current theme programmatically in Android (Xamarin)

Use this code I have tested

For WindowBackground :

Code :

Android.Util.TypedValue a = new Android.Util.TypedValue();
Theme.ResolveAttribute(Android.Resource.Attribute.WindowBackground, a , true);
var windowBackgroundDrawable = Application.Context.GetDrawable(a.ResourceId);
var windowBackgroundColor = ((Android.Graphics.Drawables.ColorDrawable)windowBackgroundD‌​rawable).Color;

Output My Case is : FAFAFA

For ColorPrimary use this :

Code :

Android.Util.TypedValue a = new Android.Util.TypedValue();
Theme.ResolveAttribute(Android.Resource.Attribute.ColorPrimary, a , true);
var colorPrimarya = Application.Context.GetDrawable(a.ResourceId);
var colorPrimary = ((Android.Graphics.Drawables.ColorDrawable) colorPrimarya).Color;

Output My Case is : 0072BA

how to get theme color programmatically in android java?

To get the value of an attribute in your theme you can use something like:

val typedValue = TypedValue();
theme.resolveAttribute(R.attr.colorPrimary, typedValue, true);
val color = ContextCompat.getColor(this, typedValue.resourceId)

button.setBackgroundColor(color)

or in java:

TypedValue typedValue = new TypedValue();
getTheme().resolveAttribute(R.attr.colorSecondary, typedValue, true);
int color = ContextCompat.getColor(this, typedValue.resourceId);

button.setBackgroundColor(color);

Get color value programmatically when it's a reference (theme)

This should do the job:

TypedValue typedValue = new TypedValue();
Theme theme = context.getTheme();
theme.resolveAttribute(R.attr.theme_color, typedValue, true);
@ColorInt int color = typedValue.data;

Also make sure to apply the theme to your Activity before calling this code. Either use:

android:theme="@style/Theme.BlueTheme"

in your manifest or call (before you call setContentView(int)):

setTheme(R.style.Theme_BlueTheme)

in onCreate().

I've tested it with your values and it worked perfectly.

Getting colors from current user selected theme

Thank you very much you both lead me in the right direction !
I found just what I was looking for.
You can get my function for collecting color schemes colors at the bottom of this post.

The solution was :

ColorSchemes files or .icls files look like this :

<scheme name="ThemeName" version="142" parent_scheme="Darcula">
<metaInfo>
</metaInfo>
<colors>
<option name="ADDED_LINES_COLOR" value="98c379" />
</colors>
<attributes>
<option name="ABSTRACT_CLASS_NAME_ATTRIBUTES">
<value>
<option name="FOREGROUND" value="e6c07b" />
</value>
</option>
</attributes>
</scheme>

You can get those colors programmatically , in java (sorry I don't know how to do it in Kotlin) you can fetch the current color scheme by doing :

EditorColorsScheme colorsScheme = EditorColorsManager.getInstance().getSchemeForCurrentUITheme();

Or you can get the default color scheme by doing :

EditorColorsScheme colorsScheme = = EditorColorsManager.getInstance().getScheme(EditorColorsManager.getInstance().getAllSchemes()[0].getName());

From that I've made a simple function that can fetch a specific color by its name (attribute and colors). If the name given does not correspond to a color defined in <attributes> it will look in the <colors> section. You can also precise if you specifically want the background color of an attribute.

Here is the function :

public Color fetchIJColor(String name, boolean isBackground){
Color c = colorsScheme.getAttributes(TextAttributesKey.createTextAttributesKey(name)).getForegroundColor();
if(c == null || isBackground){
c = colorsScheme.getAttributes(TextAttributesKey.createTextAttributesKey(name)).getBackgroundColor();
}
if(c == null){
c = colorsScheme.getColor(ColorKey.createColorKey(name));
}
return c;
}

Get background color of a Layout

This can only be accomplished in API 11+ if your background is a solid color.

int color = Color.TRANSPARENT;
Drawable background = view.getBackground();
if (background instanceof ColorDrawable)
color = ((ColorDrawable) background).getColor();


Related Topics



Leave a reply



Submit