Sahil Dave
Sahil Dave

Reputation: 433

Cannot find if a view is not visible on screen in a ScrollView. Always returns true

I have been trying to determine if a TextView can be seen on the screen, if not I want to display a small text saying "Scroll To Read". I have tried various methods from questions like this and many others too. In the detail fragment of my Master-Detail Layout, I have a fragment, which contains a FrameLayout. This framelayout has a ScrollView in the back and a textview in the front saying "Scroll To Read" (which I would keep invisible until the textview with news article in the scrollview is not visible). For eg, I wont display the "Scroll To Read" textview here or here, but would display here. Right now, it is visible just for testing purposes.

The layout is here. The scrollview is scroller. When image is available viewstub article_header_stub_import is used which is given in the bottom of the file. I want to check if TextView body is visible or not. I added wastedText below the body just for checking but it was also shown visible in all cases.

I have tried different things with the solutions, like getting getHitRect with scrollingLinearLayout or scroller or detailFrameLayout and even with the detail fragment. The code is similar to the question I linked and I am just using Log.d(...) to see check with the if-else case.

I am using Picasso to load the image and doing the coding in the success callback of picasso, for eg this:

picassoInstance.load(mImageURL).into(mMainImageView, new Callback() {

            @Override
            public void onSuccess() {
                Log.d(TAG_ASYNC, "Image Loaded");
                mTestTextView.setVisibility(View.VISIBLE);

                Rect scrollBounds = new Rect();
                mScrollView.getHitRect(scrollBounds);
                if (mTestTextView.getLocalVisibleRect(scrollBounds)) {
                    // Any portion of the imageView, even a single pixel, is
                    // within the visible window
                    Log.d(TAG_ASYNC, "is visible");
                } else {
                    // NONE of the imageView is within the visible window
                    Log.d(TAG_ASYNC, "not visible");
                }

            }

            @Override
            public void onError() {
                // TODO Auto-generated method stub

            }
        });

I have also tried getHeight, getTop, getBottom etc. but all returns 0.

Upvotes: 1

Views: 610

Answers (1)

Sahil Dave
Sahil Dave

Reputation: 433

I was not able to use the Rect. So I searched for "view getheight is always 0". Although I still dont understand why the height was returning 0 (although this is happening in onPostExecute of AsyncTask AND after the image is loaded by Picasso), I used the GlobalListener to get the height and compare with the screen.

picassoInstance.load(mImageURL).into(mMainImageView, new Callback() {

@Override
public void onSuccess() {
    Log.d(TAG_ASYNC, "Image Loaded");

    mMainImageView.getViewTreeObserver().addOnGlobalLayoutListener(
            new ViewTreeObserver.OnGlobalLayoutListener() {

                @SuppressWarnings("deprecation")
                @SuppressLint("NewApi")
                @Override
                public void onGlobalLayout() {

                    //Get Display metrics according to the SDK
                    Display display = getWindowManager().getDefaultDisplay();
                    Point screen = new Point();
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
                        display.getSize(screen);
                    } else {
                        screen.x = display.getWidth();
                        screen.y = display.getHeight();
                    }

                    //StatusBar Height
                    int statusBarHeight = 0;
                    int resId = getResources().getIdentifier("status_bar_height", "dimen", "android");
                    if (resId > 0) {
                        statusBarHeight = getResources().getDimensionPixelSize(resId);
                    }

                    //ActionBar Height
                    TypedValue tv = new TypedValue();
                    int actionBarHeight = 0;
                    if (getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true)) {
                        actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data,
                                getResources().getDisplayMetrics());
                    }

                    //Check
                    Log.d(TAG_ASYNC, "mSubtitleLayout " + mSubtitleLayout.getHeight());
                    Log.d(TAG_ASYNC, "mMainImageView " + mMainImageView.getHeight());
                    Log.d(TAG_ASYNC, "mArticleTextView " + mArticleTextView.getTop());
                    Log.d(TAG_ASYNC, "total height " + screen.y);
                    Log.d(TAG_ASYNC, "status bar " + statusBarHeight);
                    Log.d(TAG_ASYNC, "action bar " + actionBarHeight);

                    //Boolean to check if image+subtitle is large enough.
                    //If yes, then display "Scroll To Read"
                    displayScrollToRead = (screen.y - statusBarHeight - actionBarHeight) < (mArticleTextView
                            .getTop()) * 1.08;
                    Log.d(TAG_ASYNC, "displayScrollToRead " + displayScrollToRead);

                    if (displayScrollToRead) {
                        mScrollToReadLayout.setVisibility(View.VISIBLE);
                        Log.d(TAG_ASYNC, "Visiblity - " + mScrollToReadLayout.getVisibility());
                    }

                    //remove GlobalLayoutListener according to SDK
                    if (Build.VERSION.SDK_INT > Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) {
                        mMainImageView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                    } else {
                        mMainImageView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
                    }

                }

            });

}

@Override
public void onError() {

    Log.d(TAG_ASYNC, "IMAGE WAS NOT LOADED!!!");

}
});

Upvotes: 1

Related Questions