Hamz4h_ Hamz4h_ - 1 year ago 52
Android Question

Determine if a view is on screen - Android

I'm a little bit stuck with this one - first and foremost, the following link has been useful however I've come up with a bit of an issue with visibility:

The link: Check view visibility

I have a scroll view (parent) and a number of sub-views (

) etc. There are a number of items I set to
within the XML (

I have some simple code to determine whether it is visible or not using
however when I set the item to
and try to immediately
I get a Rect with zeros across the board. Any further click gets the correct coordinates.

Now this could be because the view has never been drawn (as defined in the XML) causing it to return no coordinates however I do set
before trying to determine screen visibility. Could it be that I need to get some kind of callback from say the onDraw()? or perhaps set the view visibility of hidden items within code. A bit annoying ;(

Some code:

Rect scrollBounds = new Rect();

Rect viewBounds = new Rect();

if (view.getVisibility() == View.GONE) {

if (!Rect.intersects(scrollBounds, viewBounds) {
// do somthing

Layouts area as follows:

  • ScrollView

    • LinearLayout

      • TableLayout

        • Button

        • HiddenView

Of course, it's highly likely I'm going about this the wrong way altogether - basically I just want to make sure that the scrollview positions itself so the view that has become visible can be seen in it's entirety.

If any other information is required, let me know!

Answer Source

Ok so thanks to OceanLife for pointing me in the right direction! There was indeed a callback required and ViewTreeObserver.OnGlobalLayoutListener() did the trick. I ended up implementing the listener against my fragment class and picked it up where I needed it. Thanks for the warning too regarding the multiple calls, I resolved this using the removeOnGlobalLayoutListener() method - works a charm.



// vto initialised in my onCreateView() method

vto = getView().getViewTreeObserver();


    public void onGlobalLayout() {

        final int i[] = new int[2];
        final Rect scrollBounds = new Rect();


        if (i[1] >= scrollBounds.bottom) {
            sView.post(new Runnable() {
                public void run() {
                    sView.smoothScrollTo(0, sView.getScrollY() + (i[1] - scrollBounds.bottom));


Just got to do some cleaning up now ...