0

I have a RelativeLayout with a unique id and this configuration:

android:background="@color/popup_background"

The value of popup_background is #EDEDED and there are other color definitions that has this same value.

On this RelativeLayout with that unique id, I then sometimes set a new color like this:

myLayout.setBackgroundColor(getResources().getColor(R.color.popup_background_red));

The value of popup_background_red is #E3463D and this works just fine.

Now comes the problem. On some devices (e.g. Samsung Galaxy S3 and a old Google Nexus S and probably others), some of the other layouts in other views that has the background set to a color definition with the value #EDEDED is now displayed with the color #E3463D, although setBackgroundColor was never called on those layouts and they are completely different layouts with their own unique id's and living in totally different views. And to make things worse, it seems pretty random what layouts are effected (not always the same even on the same device) and only some de devices has this problem.

Does anybody have a clue to what is going on here? Can I do something to prevent this?

Thank you
Søren

JBirdVegas
  • 10,855
  • 2
  • 44
  • 50
Neigaard
  • 3,726
  • 9
  • 49
  • 85
  • Very odd issue. Never encountered this before. I use S3 for testing nearly 4 applications and not once did this issue pop up. – Henry Oct 21 '15 at 06:54
  • Can you try extracting the color to a ColorDrawable variable, then setting it as a drawable? `Drawable myColor = new ColorDrawable(getResources().getColor(R.color.popup_background_red)); myLayout.setBackground(myColor);` – ataulm Oct 21 '15 at 06:54

2 Answers2

0

I'm 99% sure this is due to resource caching. If you check the code for setBackgroundColor(int color) on the version of View included in the latest version of the SDK:

public void setBackgroundColor(@ColorInt int color) {
    if (mBackground instanceof ColorDrawable) {
        ((ColorDrawable) mBackground.mutate()).setColor(color);
        computeOpaqueFlags();
        mBackgroundResource = 0;
    } else {
        setBackground(new ColorDrawable(color));
    }
}

you'll notice the .mutate(). I suspect that the test devices that you see this issue on has a different version of View that does not include this call to mutate().

So, as I mentioned in the comment on the question, you can create a new ColorDrawable() for this View to make sure that all the other Views that use popup_background are not all changing at the same time (due to the shared constant state).

ataulm
  • 15,195
  • 7
  • 50
  • 92
0

Try using setBackgoundDrawable(new ColorDrawable(color))) rather than setBackground(color).

Why you have to do this is explained here: https://stackoverflow.com/a/14875176/4747587

Community
  • 1
  • 1
Henry
  • 17,490
  • 7
  • 63
  • 98