Loading core/java/android/view/View.java +59 −3 Original line number Original line Diff line number Diff line Loading @@ -1442,6 +1442,27 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility */ */ static final int DIRTY_MASK = 0x00600000; 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. * The parent this view is attached to. * {@hide} * {@hide} Loading Loading @@ -2014,6 +2035,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility setScrollContainer(true); setScrollContainer(true); } } computeOpaqueFlags(); a.recycle(); a.recycle(); } } Loading Loading @@ -4700,7 +4723,35 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility */ */ @ViewDebug.ExportedProperty @ViewDebug.ExportedProperty public boolean isOpaque() { 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; } } /** /** Loading Loading @@ -5027,6 +5078,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility public void setHorizontalScrollBarEnabled(boolean horizontalScrollBarEnabled) { public void setHorizontalScrollBarEnabled(boolean horizontalScrollBarEnabled) { if (isHorizontalScrollBarEnabled() != horizontalScrollBarEnabled) { if (isHorizontalScrollBarEnabled() != horizontalScrollBarEnabled) { mViewFlags ^= SCROLLBARS_HORIZONTAL; mViewFlags ^= SCROLLBARS_HORIZONTAL; computeOpaqueFlags(); recomputePadding(); recomputePadding(); } } } } Loading Loading @@ -5056,6 +5108,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility public void setVerticalScrollBarEnabled(boolean verticalScrollBarEnabled) { public void setVerticalScrollBarEnabled(boolean verticalScrollBarEnabled) { if (isVerticalScrollBarEnabled() != verticalScrollBarEnabled) { if (isVerticalScrollBarEnabled() != verticalScrollBarEnabled) { mViewFlags ^= SCROLLBARS_VERTICAL; mViewFlags ^= SCROLLBARS_VERTICAL; computeOpaqueFlags(); recomputePadding(); recomputePadding(); } } } } Loading Loading @@ -5084,6 +5137,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility public void setScrollBarStyle(int style) { public void setScrollBarStyle(int style) { if (style != (mViewFlags & SCROLLBARS_STYLE_MASK)) { if (style != (mViewFlags & SCROLLBARS_STYLE_MASK)) { mViewFlags = (mViewFlags & ~SCROLLBARS_STYLE_MASK) | (style & SCROLLBARS_STYLE_MASK); mViewFlags = (mViewFlags & ~SCROLLBARS_STYLE_MASK) | (style & SCROLLBARS_STYLE_MASK); computeOpaqueFlags(); recomputePadding(); recomputePadding(); } } } } Loading Loading @@ -6848,6 +6902,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility requestLayout = true; requestLayout = true; } } computeOpaqueFlags(); if (requestLayout) { if (requestLayout) { requestLayout(); requestLayout(); } } Loading core/java/android/widget/ListView.java +42 −18 Original line number Original line Diff line number Diff line Loading @@ -21,6 +21,7 @@ import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Canvas; import android.graphics.Rect; import android.graphics.Rect; import android.graphics.PixelFormat; import android.graphics.PixelFormat; import android.graphics.Paint; import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.ColorDrawable; import android.os.Parcel; import android.os.Parcel; Loading Loading @@ -133,6 +134,7 @@ public class ListView extends AbsListView { // used for temporary calculations. // used for temporary calculations. private final Rect mTempRect = new Rect(); private final Rect mTempRect = new Rect(); private Paint mDividerPaint; // the single allocated result per list view; kinda cheesey but avoids // the single allocated result per list view; kinda cheesey but avoids // allocating these thingies too often. // allocating these thingies too often. Loading Loading @@ -2813,12 +2815,20 @@ public class ListView extends AbsListView { */ */ @Override @Override public boolean isOpaque() { public boolean isOpaque() { return (mCachingStarted && mIsCacheColorOpaque && mDividerIsOpaque) || super.isOpaque(); return (mCachingStarted && mIsCacheColorOpaque && mDividerIsOpaque && hasOpaqueScrollbars()) || super.isOpaque(); } } @Override @Override public void setCacheColorHint(int color) { 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); super.setCacheColorHint(color); } } Loading @@ -2841,6 +2851,8 @@ public class ListView extends AbsListView { final int first = mFirstPosition; final int first = mFirstPosition; final boolean areAllItemsSelectable = mAreAllItemsSelectable; final boolean areAllItemsSelectable = mAreAllItemsSelectable; final ListAdapter adapter = mAdapter; final ListAdapter adapter = mAdapter; final boolean isOpaque = isOpaque(); final Paint paint = mDividerPaint; if (!mStackFromBottom) { if (!mStackFromBottom) { int bottom; int bottom; Loading @@ -2852,12 +2864,18 @@ public class ListView extends AbsListView { View child = getChildAt(i); View child = getChildAt(i); bottom = child.getBottom(); bottom = child.getBottom(); // Don't draw dividers next to items that are not enabled // Don't draw dividers next to items that are not enabled if (bottom < listBottom && (areAllItemsSelectable || if (bottom < listBottom) { if ((areAllItemsSelectable || (adapter.isEnabled(first + i) && (i == count - 1 || (adapter.isEnabled(first + i) && (i == count - 1 || adapter.isEnabled(first + i + 1))))) { adapter.isEnabled(first + i + 1))))) { bounds.top = bottom; bounds.top = bottom; bounds.bottom = bottom + dividerHeight; bounds.bottom = bottom + dividerHeight; drawDivider(canvas, bounds, i); drawDivider(canvas, bounds, i); } else if (isOpaque) { bounds.top = bottom; bounds.bottom = bottom + dividerHeight; canvas.drawRect(bounds, paint); } } } } } } } Loading @@ -2871,7 +2889,8 @@ public class ListView extends AbsListView { View child = getChildAt(i); View child = getChildAt(i); top = child.getTop(); top = child.getTop(); // Don't draw dividers next to items that are not enabled // Don't draw dividers next to items that are not enabled if (top > listTop && (areAllItemsSelectable || if (top > listTop) { if ((areAllItemsSelectable || (adapter.isEnabled(first + i) && (i == count - 1 || (adapter.isEnabled(first + i) && (i == count - 1 || adapter.isEnabled(first + i + 1))))) { adapter.isEnabled(first + i + 1))))) { bounds.top = top - dividerHeight; bounds.top = top - dividerHeight; Loading @@ -2881,6 +2900,11 @@ public class ListView extends AbsListView { // position. Give -1 when there is no child above the // position. Give -1 when there is no child above the // divider. // divider. drawDivider(canvas, bounds, i - 1); drawDivider(canvas, bounds, i - 1); } else if (isOpaque) { bounds.top = top - dividerHeight; bounds.bottom = top; canvas.drawRect(bounds, paint); } } } } } } } Loading Loading
core/java/android/view/View.java +59 −3 Original line number Original line Diff line number Diff line Loading @@ -1442,6 +1442,27 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility */ */ static final int DIRTY_MASK = 0x00600000; 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. * The parent this view is attached to. * {@hide} * {@hide} Loading Loading @@ -2014,6 +2035,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility setScrollContainer(true); setScrollContainer(true); } } computeOpaqueFlags(); a.recycle(); a.recycle(); } } Loading Loading @@ -4700,7 +4723,35 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility */ */ @ViewDebug.ExportedProperty @ViewDebug.ExportedProperty public boolean isOpaque() { 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; } } /** /** Loading Loading @@ -5027,6 +5078,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility public void setHorizontalScrollBarEnabled(boolean horizontalScrollBarEnabled) { public void setHorizontalScrollBarEnabled(boolean horizontalScrollBarEnabled) { if (isHorizontalScrollBarEnabled() != horizontalScrollBarEnabled) { if (isHorizontalScrollBarEnabled() != horizontalScrollBarEnabled) { mViewFlags ^= SCROLLBARS_HORIZONTAL; mViewFlags ^= SCROLLBARS_HORIZONTAL; computeOpaqueFlags(); recomputePadding(); recomputePadding(); } } } } Loading Loading @@ -5056,6 +5108,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility public void setVerticalScrollBarEnabled(boolean verticalScrollBarEnabled) { public void setVerticalScrollBarEnabled(boolean verticalScrollBarEnabled) { if (isVerticalScrollBarEnabled() != verticalScrollBarEnabled) { if (isVerticalScrollBarEnabled() != verticalScrollBarEnabled) { mViewFlags ^= SCROLLBARS_VERTICAL; mViewFlags ^= SCROLLBARS_VERTICAL; computeOpaqueFlags(); recomputePadding(); recomputePadding(); } } } } Loading Loading @@ -5084,6 +5137,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility public void setScrollBarStyle(int style) { public void setScrollBarStyle(int style) { if (style != (mViewFlags & SCROLLBARS_STYLE_MASK)) { if (style != (mViewFlags & SCROLLBARS_STYLE_MASK)) { mViewFlags = (mViewFlags & ~SCROLLBARS_STYLE_MASK) | (style & SCROLLBARS_STYLE_MASK); mViewFlags = (mViewFlags & ~SCROLLBARS_STYLE_MASK) | (style & SCROLLBARS_STYLE_MASK); computeOpaqueFlags(); recomputePadding(); recomputePadding(); } } } } Loading Loading @@ -6848,6 +6902,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility requestLayout = true; requestLayout = true; } } computeOpaqueFlags(); if (requestLayout) { if (requestLayout) { requestLayout(); requestLayout(); } } Loading
core/java/android/widget/ListView.java +42 −18 Original line number Original line Diff line number Diff line Loading @@ -21,6 +21,7 @@ import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Canvas; import android.graphics.Rect; import android.graphics.Rect; import android.graphics.PixelFormat; import android.graphics.PixelFormat; import android.graphics.Paint; import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.ColorDrawable; import android.os.Parcel; import android.os.Parcel; Loading Loading @@ -133,6 +134,7 @@ public class ListView extends AbsListView { // used for temporary calculations. // used for temporary calculations. private final Rect mTempRect = new Rect(); private final Rect mTempRect = new Rect(); private Paint mDividerPaint; // the single allocated result per list view; kinda cheesey but avoids // the single allocated result per list view; kinda cheesey but avoids // allocating these thingies too often. // allocating these thingies too often. Loading Loading @@ -2813,12 +2815,20 @@ public class ListView extends AbsListView { */ */ @Override @Override public boolean isOpaque() { public boolean isOpaque() { return (mCachingStarted && mIsCacheColorOpaque && mDividerIsOpaque) || super.isOpaque(); return (mCachingStarted && mIsCacheColorOpaque && mDividerIsOpaque && hasOpaqueScrollbars()) || super.isOpaque(); } } @Override @Override public void setCacheColorHint(int color) { 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); super.setCacheColorHint(color); } } Loading @@ -2841,6 +2851,8 @@ public class ListView extends AbsListView { final int first = mFirstPosition; final int first = mFirstPosition; final boolean areAllItemsSelectable = mAreAllItemsSelectable; final boolean areAllItemsSelectable = mAreAllItemsSelectable; final ListAdapter adapter = mAdapter; final ListAdapter adapter = mAdapter; final boolean isOpaque = isOpaque(); final Paint paint = mDividerPaint; if (!mStackFromBottom) { if (!mStackFromBottom) { int bottom; int bottom; Loading @@ -2852,12 +2864,18 @@ public class ListView extends AbsListView { View child = getChildAt(i); View child = getChildAt(i); bottom = child.getBottom(); bottom = child.getBottom(); // Don't draw dividers next to items that are not enabled // Don't draw dividers next to items that are not enabled if (bottom < listBottom && (areAllItemsSelectable || if (bottom < listBottom) { if ((areAllItemsSelectable || (adapter.isEnabled(first + i) && (i == count - 1 || (adapter.isEnabled(first + i) && (i == count - 1 || adapter.isEnabled(first + i + 1))))) { adapter.isEnabled(first + i + 1))))) { bounds.top = bottom; bounds.top = bottom; bounds.bottom = bottom + dividerHeight; bounds.bottom = bottom + dividerHeight; drawDivider(canvas, bounds, i); drawDivider(canvas, bounds, i); } else if (isOpaque) { bounds.top = bottom; bounds.bottom = bottom + dividerHeight; canvas.drawRect(bounds, paint); } } } } } } } Loading @@ -2871,7 +2889,8 @@ public class ListView extends AbsListView { View child = getChildAt(i); View child = getChildAt(i); top = child.getTop(); top = child.getTop(); // Don't draw dividers next to items that are not enabled // Don't draw dividers next to items that are not enabled if (top > listTop && (areAllItemsSelectable || if (top > listTop) { if ((areAllItemsSelectable || (adapter.isEnabled(first + i) && (i == count - 1 || (adapter.isEnabled(first + i) && (i == count - 1 || adapter.isEnabled(first + i + 1))))) { adapter.isEnabled(first + i + 1))))) { bounds.top = top - dividerHeight; bounds.top = top - dividerHeight; Loading @@ -2881,6 +2900,11 @@ public class ListView extends AbsListView { // position. Give -1 when there is no child above the // position. Give -1 when there is no child above the // divider. // divider. drawDivider(canvas, bounds, i - 1); drawDivider(canvas, bounds, i - 1); } else if (isOpaque) { bounds.top = top - dividerHeight; bounds.bottom = top; canvas.drawRect(bounds, paint); } } } } } } } Loading