Merge change 1825 into donut
* changes: Fixes #1855461, #1857290 and #1857365. Certain scrollbar styles make an opaque view not be opaque. ListView and View now account for this when indicating whether they are opaque or not.
This commit is contained in:
@@ -1442,6 +1442,27 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
|
||||
*/
|
||||
static final int DIRTY_MASK = 0x00600000;
|
||||
|
||||
/**
|
||||
* Indicates whether the background is opaque.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
static final int OPAQUE_BACKGROUND = 0x00800000;
|
||||
|
||||
/**
|
||||
* Indicates whether the scrollbars are opaque.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
static final int OPAQUE_SCROLLBARS = 0x01000000;
|
||||
|
||||
/**
|
||||
* Indicates whether the view is opaque.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
static final int OPAQUE_MASK = 0x01800000;
|
||||
|
||||
/**
|
||||
* The parent this view is attached to.
|
||||
* {@hide}
|
||||
@@ -1721,7 +1742,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
|
||||
public View(Context context) {
|
||||
mContext = context;
|
||||
mResources = context != null ? context.getResources() : null;
|
||||
mViewFlags = SOUND_EFFECTS_ENABLED|HAPTIC_FEEDBACK_ENABLED;
|
||||
mViewFlags = SOUND_EFFECTS_ENABLED | HAPTIC_FEEDBACK_ENABLED;
|
||||
++sInstanceCount;
|
||||
}
|
||||
|
||||
@@ -2013,7 +2034,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
|
||||
if (!setScrollContainer && (viewFlagValues&SCROLLBARS_VERTICAL) != 0) {
|
||||
setScrollContainer(true);
|
||||
}
|
||||
|
||||
|
||||
computeOpaqueFlags();
|
||||
|
||||
a.recycle();
|
||||
}
|
||||
|
||||
@@ -4700,7 +4723,35 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
|
||||
*/
|
||||
@ViewDebug.ExportedProperty
|
||||
public boolean isOpaque() {
|
||||
return mBGDrawable != null && mBGDrawable.getOpacity() == PixelFormat.OPAQUE;
|
||||
return (mPrivateFlags & OPAQUE_MASK) == OPAQUE_MASK;
|
||||
}
|
||||
|
||||
private void computeOpaqueFlags() {
|
||||
// Opaque if:
|
||||
// - Has a background
|
||||
// - Background is opaque
|
||||
// - Doesn't have scrollbars or scrollbars are inside overlay
|
||||
|
||||
if (mBGDrawable != null && mBGDrawable.getOpacity() == PixelFormat.OPAQUE) {
|
||||
mPrivateFlags |= OPAQUE_BACKGROUND;
|
||||
} else {
|
||||
mPrivateFlags &= ~OPAQUE_BACKGROUND;
|
||||
}
|
||||
|
||||
final int flags = mViewFlags;
|
||||
if (((flags & SCROLLBARS_VERTICAL) == 0 && (flags & SCROLLBARS_HORIZONTAL) == 0) ||
|
||||
(flags & SCROLLBARS_STYLE_MASK) == SCROLLBARS_INSIDE_OVERLAY) {
|
||||
mPrivateFlags |= OPAQUE_SCROLLBARS;
|
||||
} else {
|
||||
mPrivateFlags &= ~OPAQUE_SCROLLBARS;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
protected boolean hasOpaqueScrollbars() {
|
||||
return (mPrivateFlags & OPAQUE_SCROLLBARS) == OPAQUE_SCROLLBARS;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -5027,6 +5078,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
|
||||
public void setHorizontalScrollBarEnabled(boolean horizontalScrollBarEnabled) {
|
||||
if (isHorizontalScrollBarEnabled() != horizontalScrollBarEnabled) {
|
||||
mViewFlags ^= SCROLLBARS_HORIZONTAL;
|
||||
computeOpaqueFlags();
|
||||
recomputePadding();
|
||||
}
|
||||
}
|
||||
@@ -5056,6 +5108,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
|
||||
public void setVerticalScrollBarEnabled(boolean verticalScrollBarEnabled) {
|
||||
if (isVerticalScrollBarEnabled() != verticalScrollBarEnabled) {
|
||||
mViewFlags ^= SCROLLBARS_VERTICAL;
|
||||
computeOpaqueFlags();
|
||||
recomputePadding();
|
||||
}
|
||||
}
|
||||
@@ -5084,6 +5137,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
|
||||
public void setScrollBarStyle(int style) {
|
||||
if (style != (mViewFlags & SCROLLBARS_STYLE_MASK)) {
|
||||
mViewFlags = (mViewFlags & ~SCROLLBARS_STYLE_MASK) | (style & SCROLLBARS_STYLE_MASK);
|
||||
computeOpaqueFlags();
|
||||
recomputePadding();
|
||||
}
|
||||
}
|
||||
@@ -6848,6 +6902,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
|
||||
requestLayout = true;
|
||||
}
|
||||
|
||||
computeOpaqueFlags();
|
||||
|
||||
if (requestLayout) {
|
||||
requestLayout();
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import android.content.res.TypedArray;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.os.Parcel;
|
||||
@@ -133,6 +134,7 @@ public class ListView extends AbsListView {
|
||||
|
||||
// used for temporary calculations.
|
||||
private final Rect mTempRect = new Rect();
|
||||
private Paint mDividerPaint;
|
||||
|
||||
// the single allocated result per list view; kinda cheesey but avoids
|
||||
// allocating these thingies too often.
|
||||
@@ -2813,12 +2815,20 @@ public class ListView extends AbsListView {
|
||||
*/
|
||||
@Override
|
||||
public boolean isOpaque() {
|
||||
return (mCachingStarted && mIsCacheColorOpaque && mDividerIsOpaque) || super.isOpaque();
|
||||
return (mCachingStarted && mIsCacheColorOpaque && mDividerIsOpaque &&
|
||||
hasOpaqueScrollbars()) || super.isOpaque();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCacheColorHint(int color) {
|
||||
mIsCacheColorOpaque = (color >>> 24) == 0xFF;
|
||||
final boolean opaque = (color >>> 24) == 0xFF;
|
||||
mIsCacheColorOpaque = opaque;
|
||||
if (opaque) {
|
||||
if (mDividerPaint == null) {
|
||||
mDividerPaint = new Paint();
|
||||
}
|
||||
mDividerPaint.setColor(color);
|
||||
}
|
||||
super.setCacheColorHint(color);
|
||||
}
|
||||
|
||||
@@ -2841,6 +2851,8 @@ public class ListView extends AbsListView {
|
||||
final int first = mFirstPosition;
|
||||
final boolean areAllItemsSelectable = mAreAllItemsSelectable;
|
||||
final ListAdapter adapter = mAdapter;
|
||||
final boolean isOpaque = isOpaque();
|
||||
final Paint paint = mDividerPaint;
|
||||
|
||||
if (!mStackFromBottom) {
|
||||
int bottom;
|
||||
@@ -2852,12 +2864,18 @@ public class ListView extends AbsListView {
|
||||
View child = getChildAt(i);
|
||||
bottom = child.getBottom();
|
||||
// Don't draw dividers next to items that are not enabled
|
||||
if (bottom < listBottom && (areAllItemsSelectable ||
|
||||
(adapter.isEnabled(first + i) && (i == count - 1 ||
|
||||
adapter.isEnabled(first + i + 1))))) {
|
||||
bounds.top = bottom;
|
||||
bounds.bottom = bottom + dividerHeight;
|
||||
drawDivider(canvas, bounds, i);
|
||||
if (bottom < listBottom) {
|
||||
if ((areAllItemsSelectable ||
|
||||
(adapter.isEnabled(first + i) && (i == count - 1 ||
|
||||
adapter.isEnabled(first + i + 1))))) {
|
||||
bounds.top = bottom;
|
||||
bounds.bottom = bottom + dividerHeight;
|
||||
drawDivider(canvas, bounds, i);
|
||||
} else if (isOpaque) {
|
||||
bounds.top = bottom;
|
||||
bounds.bottom = bottom + dividerHeight;
|
||||
canvas.drawRect(bounds, paint);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2871,16 +2889,22 @@ public class ListView extends AbsListView {
|
||||
View child = getChildAt(i);
|
||||
top = child.getTop();
|
||||
// Don't draw dividers next to items that are not enabled
|
||||
if (top > listTop && (areAllItemsSelectable ||
|
||||
(adapter.isEnabled(first + i) && (i == count - 1 ||
|
||||
adapter.isEnabled(first + i + 1))))) {
|
||||
bounds.top = top - dividerHeight;
|
||||
bounds.bottom = top;
|
||||
// Give the method the child ABOVE the divider, so we
|
||||
// subtract one from our child
|
||||
// position. Give -1 when there is no child above the
|
||||
// divider.
|
||||
drawDivider(canvas, bounds, i - 1);
|
||||
if (top > listTop) {
|
||||
if ((areAllItemsSelectable ||
|
||||
(adapter.isEnabled(first + i) && (i == count - 1 ||
|
||||
adapter.isEnabled(first + i + 1))))) {
|
||||
bounds.top = top - dividerHeight;
|
||||
bounds.bottom = top;
|
||||
// Give the method the child ABOVE the divider, so we
|
||||
// subtract one from our child
|
||||
// position. Give -1 when there is no child above the
|
||||
// divider.
|
||||
drawDivider(canvas, bounds, i - 1);
|
||||
} else if (isOpaque) {
|
||||
bounds.top = top - dividerHeight;
|
||||
bounds.bottom = top;
|
||||
canvas.drawRect(bounds, paint);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user