A strange miscalculation when trying to detect if the WebView is scrolling down

I have a problem with detection when a WebView scrolls down. I am using the following code:

 @Override protected void onScrollChanged(int x, int y, int oldX, int oldY) { super.onScrollChanged(x, y, oldX, oldY); int bottom = ((int) Math.floor(getContentHeight() * getScale()) - getHeight()); MyLogger.log(y + "____" + bottom); if (y == bottom) { // Trigger listener } } 

Logging gives me the following result:

 162____164 

So, for some reason, 2 pixels are calculated here, and I do not know where this comes from.

Thanks.

+2
android android-webview
source share
2 answers

The calculation you have seems to be correct. This would be better expressed as:

 @Override protected void onScrollChanged(int x, int y, int oldX, int oldY) { super.onScrollChanged(x, y, oldX, oldY); final int DIRECTION_UP = 1; if (!canScrollVertically(DIRECTION_UP)) { // Trigger listener. } } 

There are several cases where you cannot find that you are at the bottom of the page as follows:

  • If the page handles scrolling using touch handlers, and pageScale () is greater than 1.0. In this case, "bottom" is detected in the CSS coordinate space and, due to rounding, may not always display correctly in the android.view.View coordinate space (although this should be fixed in KitKat).
  • You or any library you use overrides WebView.scrollTo / overScrollBy / etc .. to prevent it from scrolling to the end.

As a last resort, you can override onOverScrolled :

 @Override protected void onOverScrolled (int scrollX, int scrollY, boolean clampedX, boolean clampedY) { if (scrollY > 0 && clampedY && !startedOverScrollingY) { startedOverScrollingY = true; // Trigger listener. } super.onOverScrolled(scrollX, scrollY, clampedX, clampedY); } @Override protected void onScrollChanged(int x, int y, int oldX, int oldY) { super.onScrollChanged(x, y, oldX, oldY); if (y < oldY) startedOverScrollingY = false; } 

If this plays in the latest version of Android, you can record a bug report . It is ideal to create a minimalistic application that reproduces the problem with a blank (or trivial) page.

+5
source share

Got an exact result with the following:

 @Override protected void onScrollChanged(int x, int y, int oldX, int oldY) { super.onScrollChanged(x, y, oldX, oldY); if (y == computeVerticalScrollRange() - getHeight()) { // Trigger listener } } 
0
source share

All Articles