Dilum Jayasinghe
Dilum Jayasinghe

Reputation: 41

How to check if the ScrollView is actually displayed or not?

I have this dynamic text which will change. I need to enable the button of this layout only if the user read all the texts. (scrolled to the bottom). This is working with the method that I have implemented.

scrollView.setOnScrollChangeListener(new View.OnScrollChangeListener() {
    @Override
    public void onScrollChange(View view, int i, int i1, int i2, int i3) {
        if (isTextViewScrolledToBottom(scrollView, mTextViewNotPDF)) {
            mAgreeButton.setEnabled(true);
            mAgreeButton.setBackground(getResources().getDrawable(R.drawable.button_bg_black_rounded));
        } else {
            mAgreeButton.setEnabled(false);
            mAgreeButton.setBackground(getResources().getDrawable(R.drawable.button_bg_grey_rounded));
        }
    }
});

private boolean isTextViewScrolledToBottom(ScrollView scrollView, TextView mTextViewNotPDF) {
    int scrollViewHeight = scrollView.getHeight();
    int textViewHeight = mTextViewNotPDF.getHeight();
    int scrollY = scrollView.getScrollY();
    return (textViewHeight) <= (scrollY + scrollViewHeight);
}

But when the text is not long enough to enable the scrollView, this method (onScrollChange) will not be called and button is disabled.

I have tested these so far without a success.

Boolean isAct =  scrollView.isEnabled(); // will be true no matter it's showing or not.  
Boolean isAct1 = scrollView.isFocusable(); // will be true no matter it's showing or not.  

Upvotes: 3

Views: 109

Answers (3)

BenjyTec
BenjyTec

Reputation: 10450

In extension to the answer by Till, only check if the ScrollView is scrollable after the View has already been drawn:

ViewTreeObserver observer = scrollView.getViewTreeObserver();
observer.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
        if (!scrollView.canScrollVertically(1)) {
            myButton.setEnabled(true);
        }
    }
});

Upvotes: 3

TIMBLOCKER
TIMBLOCKER

Reputation: 438

Instead of using a RecyclerView and manually enabling the button, you could do the following:

Nest the Recyclerview in a parent Layout (e.g. ConstraintLayout) and make it so that the Button is below the RecyclerView. You could then Nest it with a (vertical) ScrollView and disable the Bar entirely with android:scrollbars="none". The Layout would then behave like you want it to. You would have to scroll down in the RecyclerView entriely until the Scrolling of the ScrollView would kick in. Then you would scroll down to the Button and it would appear. This seems to be a good soulution to your problem, because you dont have a "in-between" state.

Upvotes: 1

Till - gotohuman.com
Till - gotohuman.com

Reputation: 6015

Have you tried

scrollView.canScrollVertically(1)

(positive value to check scrolling down)?

You'd do this when your view is created (outside of your onScrollChange because it might not get called). But pay attention that the views probably need to be drawn and measured first:

scrollView.post(() -> {
    boolean canScroll = scrollView.canScrollVertically(1)
});


If this doesn't work, how about checking whether the textViewHeight is smaller than your scrollView's height? Again making sure that the views are already drawn and measured.

Upvotes: 4

Related Questions