Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Elevation in a View with transparent background

I have a list of items with a custom background. The background is a simple shape with rounded-rect drawable filled with white color. So my view is similar to a Card. I can set an elevation on it and it works. There is a shadow beneath it.

But I want to optimize it. My window's background is white, so I thought that I can remove View's background color to reduce overdraw. But it's not that simple. As soon as I set color to transparent in my view's background drawable, elevation stops working and shadow is not drawn anymore. I've tried to use stroke instead of solid color inside my view's bakcground drawable but it doesn't work too. It's probably because of a ViewOutline. So I've created a custom OutlineProvider that returns something like this:

outline.drawRoundRect(0,0,view.getWidth(), view.getHeight(), someRadius); 

Now my View has transparent background and shadow is also visible but there is something wrong with it. It does not look good. At the top of the View there is some sort of a background visible beneath it. Below is a picture of my output. On the left is a view with transparent background and a custom OutlineProvider. On the right is a view with opaque white background.

enter image description here

Is it a bug? Or is there another way to achieve this? It seems like it's a very simple performance optimization but it turns out that it's much more complicated than it should be.

like image 989
Michał Z. Avatar asked Aug 29 '15 12:08

Michał Z.


1 Answers

I believe this to be related to a known issue in Lollipop https://code.google.com/p/android/issues/detail?id=78248

Thanks for the report and repro steps - this is indeed a bug, and it has just been fixed in an internal branch. Will be released externally in a future release.

As a workaround, you can either set an alpha on the GradientDrawable, or set a custom outline provider on the view casting the shadow (via View#setOutlineProvider) to query the outline from the background and override the alpha provided by the drawable.

The issue was that GradientDrawable was being too conservative in reporting a 0 alpha in cases where it had a transparent fill. (See GradientDrawable#getOutline(), for the curious)

like image 50
Rares Barbantan Avatar answered Sep 20 '22 17:09

Rares Barbantan