Correctly report the transparent region
First, we fix the transparent region computation to use the order as the drawing. Previously, it is using the tree traverse order, not the draw order. Second, add the y offset for any view with positive z value, this will allow some space for shadow. b/30124573 Change-Id: I98d38261ffd346b762651e087cb243e45fed6952
This commit is contained in:
@@ -20269,8 +20269,14 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
|
||||
// remove it from the transparent region.
|
||||
final int[] location = attachInfo.mTransparentLocation;
|
||||
getLocationInWindow(location);
|
||||
region.op(location[0], location[1], location[0] + mRight - mLeft,
|
||||
location[1] + mBottom - mTop, Region.Op.DIFFERENCE);
|
||||
// When a view has Z value, then it will be better to leave some area below the view
|
||||
// for drawing shadow. The shadow outset is proportional to the Z value. Note that
|
||||
// the bottom part needs more offset than the left, top and right parts due to the
|
||||
// spot light effects.
|
||||
int shadowOffset = getZ() > 0 ? (int) getZ() : 0;
|
||||
region.op(location[0] - shadowOffset, location[1] - shadowOffset,
|
||||
location[0] + mRight - mLeft + shadowOffset,
|
||||
location[1] + mBottom - mTop + (shadowOffset * 3), Region.Op.DIFFERENCE);
|
||||
} else {
|
||||
if (mBackground != null && mBackground.getOpacity() != PixelFormat.TRANSPARENT) {
|
||||
// The SKIP_DRAW flag IS set and the background drawable exists, we remove
|
||||
|
||||
@@ -6406,16 +6406,28 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
|
||||
return true;
|
||||
}
|
||||
super.gatherTransparentRegion(region);
|
||||
final View[] children = mChildren;
|
||||
final int count = mChildrenCount;
|
||||
// Instead of naively traversing the view tree, we have to traverse according to the Z
|
||||
// order here. We need to go with the same order as dispatchDraw().
|
||||
// One example is that after surfaceView punch a hole, we will still allow other views drawn
|
||||
// on top of that hole. In this case, those other views should be able to cut the
|
||||
// transparent region into smaller area.
|
||||
final int childrenCount = mChildrenCount;
|
||||
boolean noneOfTheChildrenAreTransparent = true;
|
||||
for (int i = 0; i < count; i++) {
|
||||
final View child = children[i];
|
||||
if ((child.mViewFlags & VISIBILITY_MASK) == VISIBLE || child.getAnimation() != null) {
|
||||
if (!child.gatherTransparentRegion(region)) {
|
||||
noneOfTheChildrenAreTransparent = false;
|
||||
if (childrenCount > 0) {
|
||||
final ArrayList<View> preorderedList = buildOrderedChildList();
|
||||
final boolean customOrder = preorderedList == null
|
||||
&& isChildrenDrawingOrderEnabled();
|
||||
final View[] children = mChildren;
|
||||
for (int i = 0; i < childrenCount; i++) {
|
||||
final int childIndex = getAndVerifyPreorderedIndex(childrenCount, i, customOrder);
|
||||
final View child = getAndVerifyPreorderedView(preorderedList, children, childIndex);
|
||||
if ((child.mViewFlags & VISIBILITY_MASK) == VISIBLE || child.getAnimation() != null) {
|
||||
if (!child.gatherTransparentRegion(region)) {
|
||||
noneOfTheChildrenAreTransparent = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (preorderedList != null) preorderedList.clear();
|
||||
}
|
||||
return meOpaque || noneOfTheChildrenAreTransparent;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user