3

After doing a lot of research on stackoverflow and looking for answers I found that I needed to create a subclass of WebView and then do an override on OnScrollChanged etc.. I have the following code...

SearchResultsWebView.setOnScrollChangedCallback(
    new Sub_WebView_Results.OnScrollChangedCallback() {
            @Override
            public void onScroll(int l, int t) {
                int tek = (int) Math.floor(SearchResultsWebView.getContentHeight() * SearchResultsWebView.getScale());
                if (tek - SearchResultsWebView.getScrollY() == SearchResultsWebView.getHeight())
                    Toast.makeText(getActivity(), "End", Toast.LENGTH_SHORT).show();


            }
        });

HOWEVER the problem is that .getScale has been depreciated. I haven't found another way that works.

I tried using ..

          SearchResultsWebView.setWebViewClient(new WebViewClient() {
        @Override
        public void onScaleChanged(WebView view, float oldScale, float newScale) {
            super.onScaleChanged(view, oldScale, newScale);
            currentScale = newScale;
        }
    });

And then just passing the [currentScale] but it seems this never gets called so I'm at a loss on how to do this.

eqiz
  • 1,521
  • 5
  • 29
  • 51
  • Please check my answer i have provided here.. https://stackoverflow.com/questions/20998108/how-to-detect-scrollend-of-webview-in-android/68731654#68731654 – Sachin Velaga Aug 10 '21 at 18:11

4 Answers4

2

Content height for web view is returned dp and thus we need to multiply with the devices density multiplier to get the actual height of the content with the actual height i deduct the webview's height to calculate when the webview will be visible and compare with scroll y every time user picks up their finger. This is what i did, working perfectly for me.

webView.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View view, MotionEvent motionEvent) {
        if (motionEvent.getAction() == MotionEvent.ACTION_UP) {
            if (Math.floor((webView.getContentHeight() * getResources().getDisplayMetrics().density) - webView.getHeight()) == webView.getScrollY()) {

                // Bottom Reached , it is necessary to calculate content height because 
                // it changes showAgreeButton();

                return true;
            }
            return false;
        }
    });
}
Sabre
  • 4,131
  • 5
  • 36
  • 57
1

Apparently I found the answer from: How can i get the current scale of a webView(android)

Instead of WebView.getScale()

You can use: getResources().getDisplayMetrics().density

Community
  • 1
  • 1
eqiz
  • 1,521
  • 5
  • 29
  • 51
1

In order to tell if the user has scrolled to the bottom of a web view, I extended the web view and had an interface callback when the user has got to the bottom of the view onScrollChanged. Here is the code:

import android.content.Context;

import android.util.AttributeSet; import android.util.Log; import android.webkit.WebView;

public class EULAWebView extends WebView {

//declare needed constants
private final String TAG = getClass().getSimpleName();

//declare needed variables
private EULAWebInterface eulaWebInteface;
private int paddingOffset = 200;
private boolean bottomReached;

public EULAWebView(Context context, AttributeSet attrs) {
    super(context, attrs);
}

public EULAWebView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
}

public EULAWebView(Context context) {
    super(context);
}

public void setEULAScrollListener(Context context) {
    try {
        eulaWebInteface = (EULAWebInterface)context;
    } catch (ClassCastException ex) {
        Log.e(TAG, "UNABLE TO CAST CONTEXT TO EULAWebInterface");
        ex.printStackTrace();
        throw new ClassCastException();
    }
}

@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
    if(this.computeVerticalScrollRange() <= (this.computeVerticalScrollOffset() +
            this.computeVerticalScrollExtent() + this.paddingOffset)) {
        if(!bottomReached) {
            bottomReached = true;
            if(eulaWebInteface != null)
                eulaWebInteface.atBottomOfScrollView(true);
        }
    } else {
        if(bottomReached) {
            bottomReached = false;
            if(eulaWebInteface != null)
                eulaWebInteface.atBottomOfScrollView(false);
        }
    }
    super.onScrollChanged(l, t, oldl, oldt);
}

}

Here is the interface that is used to let the activity know that the bottom of the scroll view has changed:

public interface EULAWebInterface {

void atBottomOfScrollView(boolean atBottom);

}

And here is the interface implementation in the activity:

@Override
public void atBottomOfScrollView(boolean atBottom) {
    findViewById(R.id.eula_action_layout).setVisibility(atBottom ? View.VISIBLE : View.GONE);
    findViewById(R.id.eula_instruction_textview).setVisibility(atBottom ? View.GONE : View.VISIBLE);
} 
Droid Chris
  • 3,455
  • 28
  • 31
0

Try this:

@Override
protected void onScrollChanged(int x, int y, int oldx, int oldy) {
        View view = (View) getChildAt(getChildCount()-1);
        int diff = (view.getBottom()-(getHeight()+getScrollY()));// Calculate the difference in scrolling
        if( diff == 0 ){  // The bottom has been reached if the difference is 0
            Log.d(ScrollTest.LOG_TAG, "WebView: Bottom has been reached" );
        // DO SOMETHING HERE WHEN THE WEBVIEW HAS REACHED THE BOTTOM!
    }
    super.onScrollChanged(x, y, oldx, oldy);
}

Btw, why use the scaling method when the above method may work better (it's easier to implement I think)

tim687
  • 2,256
  • 2
  • 17
  • 28