diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/java/android/view/View.java | 62 | ||||
-rw-r--r-- | core/java/android/widget/ListView.java | 60 |
2 files changed, 101 insertions, 21 deletions
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 1564fd0..1f72eea 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -1443,6 +1443,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(); } diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java index c21c7fa..6686f75 100644 --- a/core/java/android/widget/ListView.java +++ b/core/java/android/widget/ListView.java @@ -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); + } } } } |