具有唯一 ID 的布局上的 setBackgroundColor 也会更改其他布局上的颜色
setBackgroundColor on a layout with a unique id also changes the color on other layouts
我有一个 RelativeLayout
具有唯一 ID 和此配置:
android:background="@color/popup_background"
popup_background 的值为 #EDEDED
,还有其他具有相同值的颜色定义。
在具有该唯一 ID 的 RelativeLayout
上,有时我会像这样设置新颜色:
myLayout.setBackgroundColor(getResources().getColor(R.color.popup_background_red));
popup_background_red
的值为 #E3463D
,这很好用。
问题来了。在某些设备上(例如 Samsung Galaxy S3 和旧的 Google Nexus S,可能还有其他设备),其他视图中的一些其他布局将背景设置为具有值 #EDEDED
的颜色定义,现在以 #E3463D
颜色显示,尽管从未在这些布局上调用 setBackgroundColor
,并且它们是完全不同的布局,具有自己独特的 ID,并且存在于完全不同的视图中。更糟糕的是,布局受到影响似乎是随机的(即使在同一设备上也不总是相同)并且只有一些设备有这个问题。
有人知道这里发生了什么吗?我可以做些什么来防止这种情况吗?
谢谢
索伦
我 99% 确定这是由于 resource caching。如果您在最新版本的 SDK 中包含的 View 版本上检查 setBackgroundColor(int color)
的代码:
public void setBackgroundColor(@ColorInt int color) {
if (mBackground instanceof ColorDrawable) {
((ColorDrawable) mBackground.mutate()).setColor(color);
computeOpaqueFlags();
mBackgroundResource = 0;
} else {
setBackground(new ColorDrawable(color));
}
}
您会注意到 .mutate()
。我怀疑你看到这个问题的测试设备有不同版本的视图,不包括对 mutate()
.
的调用
因此,正如我在对该问题的评论中提到的,您可以为此视图创建一个 new ColorDrawable()
,以确保使用 popup_background
的所有其他视图不会全部更改同时(由于 shared constant state)。
尝试使用 setBackgoundDrawable(new ColorDrawable(color)))
而不是 setBackground(color)
。
这里解释了为什么你必须这样做:
我有一个 RelativeLayout
具有唯一 ID 和此配置:
android:background="@color/popup_background"
popup_background 的值为 #EDEDED
,还有其他具有相同值的颜色定义。
在具有该唯一 ID 的 RelativeLayout
上,有时我会像这样设置新颜色:
myLayout.setBackgroundColor(getResources().getColor(R.color.popup_background_red));
popup_background_red
的值为 #E3463D
,这很好用。
问题来了。在某些设备上(例如 Samsung Galaxy S3 和旧的 Google Nexus S,可能还有其他设备),其他视图中的一些其他布局将背景设置为具有值 #EDEDED
的颜色定义,现在以 #E3463D
颜色显示,尽管从未在这些布局上调用 setBackgroundColor
,并且它们是完全不同的布局,具有自己独特的 ID,并且存在于完全不同的视图中。更糟糕的是,布局受到影响似乎是随机的(即使在同一设备上也不总是相同)并且只有一些设备有这个问题。
有人知道这里发生了什么吗?我可以做些什么来防止这种情况吗?
谢谢
索伦
我 99% 确定这是由于 resource caching。如果您在最新版本的 SDK 中包含的 View 版本上检查 setBackgroundColor(int color)
的代码:
public void setBackgroundColor(@ColorInt int color) {
if (mBackground instanceof ColorDrawable) {
((ColorDrawable) mBackground.mutate()).setColor(color);
computeOpaqueFlags();
mBackgroundResource = 0;
} else {
setBackground(new ColorDrawable(color));
}
}
您会注意到 .mutate()
。我怀疑你看到这个问题的测试设备有不同版本的视图,不包括对 mutate()
.
因此,正如我在对该问题的评论中提到的,您可以为此视图创建一个 new ColorDrawable()
,以确保使用 popup_background
的所有其他视图不会全部更改同时(由于 shared constant state)。
尝试使用 setBackgoundDrawable(new ColorDrawable(color)))
而不是 setBackground(color)
。
这里解释了为什么你必须这样做: