@@ -5088,24 +5088,35 @@ protected boolean isVisibleToUser() {
50885088 */
50895089 protected boolean isVisibleToUser(Rect boundInView) {
50905090 if (mAttachInfo != null) {
5091+ // Attached to invisible window means this view is not visible.
5092+ if (mAttachInfo.mWindowVisibility != View.VISIBLE) {
5093+ return false;
5094+ }
5095+ // An invisible predecessor or one with alpha zero means
5096+ // that this view is not visible to the user.
5097+ Object current = this;
5098+ while (current instanceof View) {
5099+ View view = (View) current;
5100+ // We have attach info so this view is attached and there is no
5101+ // need to check whether we reach to ViewRootImpl on the way up.
5102+ if (view.getAlpha() <= 0 || view.getVisibility() != VISIBLE) {
5103+ return false;
5104+ }
5105+ current = view.mParent;
5106+ }
5107+ // Check if the view is entirely covered by its predecessors.
50915108 Rect visibleRect = mAttachInfo.mTmpInvalRect;
50925109 Point offset = mAttachInfo.mPoint;
5093- // The first two checks are made also made by isShown() which
5094- // however traverses the tree up to the parent to catch that.
5095- // Therefore, we do some fail fast check to minimize the up
5096- // tree traversal.
5097- boolean isVisible = mAttachInfo.mWindowVisibility == View.VISIBLE
5098- && getAlpha() > 0
5099- && isShown()
5100- && getGlobalVisibleRect(visibleRect, offset);
5101- if (isVisible && boundInView != null) {
5110+ if (!getGlobalVisibleRect(visibleRect, offset)) {
5111+ return false;
5112+ }
5113+ // Check if the visible portion intersects the rectangle of interest.
5114+ if (boundInView != null) {
51025115 visibleRect.offset(-offset.x, -offset.y);
5103- // isVisible is always true here, use a simple assignment
5104- isVisible = boundInView.intersect(visibleRect);
5116+ return boundInView.intersect(visibleRect);
51055117 }
5106- return isVisible ;
5118+ return true ;
51075119 }
5108-
51095120 return false;
51105121 }
51115122
0 commit comments