A pit encountered using the background color alpha value in Android
preface
Android sets the alpha value, image dilution and transparency. As we all know, the following is a simple example code:
The above is a brief introduction, but this article describes a bug in the company's project that has been left for a long time. I have tried to find the reason many times and have no clue.
The bug is like this:
A theme color is defined as, for example #ff0000, which is used by many interface controls. However, when this color is used in the process of APP use, it will become transparent, and after transparency, all controls using this color will become transparent.
What's more strange is that restarting the application will recover the problem, but the operation will occur again later.
The project has an interface implementation that changes the title bar from transparent to theme color as the page scrolls, similar to the effect of AppBar in the design library. The implementation method is as follows:
Today, when implementing the feature of "code level reuse", I found that the bug was also introduced into the new project, and then I found the problem of this implementation
First, view. Getbackground () obtains a colordrawable, and then setting the alpha value of this colordrawable will affect the alpha values of all background colors that set background to this color.
Then I wrote a small demo to verify this statement, although it does not take effect immediately. Then I returned to two views with the same color background after exiting the application. Changing one of them will indeed affect the other.
The reaction was: WTF? Is it difficult that all drawable objects of the same color are the same object? However, I quickly printed the background drawable object and verified that it was not the case -- although the alpha values of colordrawable obtained by these views were the same, the hashcode was different.
So I prefer that this is a bug caused by Android memory optimization. Even if this color has an alpha value when defined, it will be ignored after modification and affect other views. This problem only exists when background is set to the ID or value of a color or setbackgroundresource is set to a color in the layout file. If you use new colordrawable (int) to construct an object with the same color value, it will not be affected. I am currently using this method to avoid this feature.
UPDATE:
This method is found in the document, which verifies the previous statement that drawable loaded from the same resource does share state, but there is a mutate method to disable this feature. The documents are as follows:
Drawable mutate ()
Make this drawable mutable. This operation cannot be reversed. A mutable drawable is guaranteed to not share its state with any other drawable. This is especially useful when you need to modify properties of drawables loaded from resources. By default,all drawables instances loaded from the same resource share a common state; if you modify the state of one instance,all the other instances will receive the same modification. Calling this method on a mutable Drawable will have no effect.
Translation:
Drawable mutate ()
Make a drawable mutable. This operation is irreversible. A mutable drawable can ensure that it will not share its status with other drawable. This method is particularly useful when a drawable is loaded from a resource and its state needs to be changed. By default, all instances of drawable from the same resource share a common state; If you change the status of one instance, all other instances will receive the same changes. Calling this method on an already variable drawable has no effect.
So, as long as drawable is acquired, the above code will call mutate () method.
summary
The above is the whole content of this article. I hope the content of this article has a certain reference value for your study or work. If you have any questions, you can leave a message. Thank you for your support for programming tips.