如何以编程方式获取当前主题的背景颜色

41

我尝试了像这样的东西,但是我卡住了:

TypedValue typedValue = new TypedValue(); 
if (this.parentActivity.getTheme().resolveAttribute(android.R.attr.windowBackground, typedValue, true))
{
  // how to get color?
}

11
在XML Android代码中,"android:background"属性的值为"?android:attr/colorBackground",表示该控件使用Android主题定义的背景颜色。 - ademar111190
4
我测试并确定 ?android:attr/colorBackground 对应于 styles.xml 中的 <item name="android:colorBackground">@color/yourColorHere</item> - Rock Lee
@ademar111190 这应该是答案!!! - Alexandr
3个回答

75

您可以通过以下方式从当前主题中获取背景颜色(或Drawable):

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在API 29级中引入。 在此之前,您可以改为使用以下内容:

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

4
好的回答。如果有人因此被绊倒,在Xamarin中,您必须使用Resource.Attribute.primaryAccentColor而不是例如Resource.Styleable.MyTheme_primaryAccentColor。这可能也适用于Android原生开发。也就是说,引用attr文件/对象而不是直接引用主题。我不明白其中的区别,但后者似乎是正确的选择,但事实上并不是。 - pbristow
pbarranis,当定义样式XML时,我的大多数颜色都使用未经限定的名称引用(<item name="someColor>),并在我自己的attrs.xml中声明;但是背景颜色是限定的(<item name="android:background">),它在Android系统中某处声明,而不是在我的attrs.xml中像其他属性一样。因此,背景颜色不是我的应用程序的属性,而是任何/每个 Android应用程序的属性。这就是区别的原因。 - jpaugh
@ashuhes FYI,我更新了你的答案,使用了最新的 API 函数 isColorType。感谢你的帮助! - jpaugh
@jpaugh 好的,知道了!感谢你更新它。 - ashughes

7

您可以使用以下方式获取主题的资源:

TypedArray a = getTheme().obtainStyledAttributes(R.style.ThemeName, new int[] {R.attr.attribute_name});     
int attributeResourceId = a.getResourceId(0, 0);

我尝试了这个:TypedArray a = this.parentActivity.getTheme().obtainStyledAttributes(android.R.attr.windowBackground, new int[] {android.R.attr.windowBackground});
int attributeResourceId = a.getResourceId(0, 0); int aaa = this.parentActivity.getResources().getColor(attributeResourceId); 但是它没有起作用。我得到了异常。
- Bartłomiej Mucha
哦!你得到了什么异常? - Swayam
09-12 12:05:34.864: E/AndroidRuntime(32137): 致命异常:主要 09-12 12:05:34.864: E/AndroidRuntime(32137): android.content.res.Resources$NotFoundException: 来自颜色状态列表资源ID#0x10804a8的文件res/drawable/screen_background_selector_light.xml 09-12 12:05:34.864: E/AndroidRuntime(32137): 在android.content.res.Resources.loadColorStateList(Resources.java) 09-12 12:05:34.864: E/AndroidRuntime(32137): 在android.content.res.Resources.getColor(Resources.java)... - Bartłomiej Mucha
android.support.v4.app.BackStackRecord.run(BackStackRecord.java:635) 在 android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1431) 处执行待定的操作 在 android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:420) 处运行 在 android.os.Handler.handleCallback(Handler.java) 处处理回调 在 android.os.Handler.dispatchMessage(Handler.java) 处分发消息 在 android.os.Looper.loop(Looper.java) 处循环 在 android.app.ActivityThread.main(ActivityThread.java) 处主线程 在 java.lang.reflect.Method.invokeNative(Native Method) 处调用本地方法 在 java.lang.reflect.Method.invoke(Method.java:511) 处调用方法 - Bartłomiej Mucha
2
它说在二进制XML文件的第18行缺少android:color属性的<item>标签。 - Swayam
显示剩余3条评论

6

对于你的问题,最简单的方法是:

TypedValue typedValue = new TypedValue(); 
if (this.parentActivity.getTheme().resolveAttribute(android.R.attr.windowBackground, typedValue, true))
{
  // how to get color?
  int colorWindowBackground = typedValue.data;// **just add this line to your code!!**
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接