Android: how to check if a View inside of ScrollView is visible?
This extension help detect view fully visible.
It also work if your View
is a child of child of ... of ScrollView
(eg: ScrollView
-> LinearLayout
-> ContraintLayout
-> ... -> YourView
).
fun ScrollView.isViewVisible(view: View): Boolean {
val scrollBounds = Rect()
this.getDrawingRect(scrollBounds)
var top = 0f
var temp = view
while (temp !is ScrollView){
top += (temp).y
temp = temp.parent as View
}
val bottom = top + view.height
return scrollBounds.top < top && scrollBounds.bottom > bottom
}
Note
1) view.getY()
and view.getX()
return the x,y value to FIRST PARENT.
2) Here is example about how getDrawingRect
will return
Link
Use View#getHitRect
instead of View#getDrawingRect
on the view you're testing. You can use View#getDrawingRect
on the ScrollView
instead of calculating explicitly.
Code from View#getDrawingRect
:
public void getDrawingRect(Rect outRect) {
outRect.left = mScrollX;
outRect.top = mScrollY;
outRect.right = mScrollX + (mRight - mLeft);
outRect.bottom = mScrollY + (mBottom - mTop);
}
Code from View#getHitRect
:
public void getHitRect(Rect outRect) {
outRect.set(mLeft, mTop, mRight, mBottom);
}
This works:
Rect scrollBounds = new Rect();
scrollView.getHitRect(scrollBounds);
if (imageView.getLocalVisibleRect(scrollBounds)) {
// Any portion of the imageView, even a single pixel, is within the visible window
} else {
// NONE of the imageView is within the visible window
}
If you want to detect that the view is FULLY visible:
private boolean isViewVisible(View view) {
Rect scrollBounds = new Rect();
mScrollView.getDrawingRect(scrollBounds);
float top = view.getY();
float bottom = top + view.getHeight();
if (scrollBounds.top < top && scrollBounds.bottom > bottom) {
return true;
} else {
return false;
}
}