Странный просчет при попытке определить, прокручивается ли WebView вниз
У меня проблема с обнаружением, когда WebView
прокручивается вниз. Я использую следующий код:
@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
}
}
Ведение журнала дает мне следующий вывод:
162____164
Так или иначе, здесь есть просчет в 2 пикселя, и я понятия не имею, откуда это происходит.
Благодарю.
2 ответа
Решение
Расчет, который вы там делаете, кажется правильным. Это было бы лучше выразить как:
@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.
}
}
Есть пара случаев, когда вы не сможете обнаружить, что находитесь внизу страницы таким образом:
- Если страница обрабатывает прокрутку с помощью сенсорных обработчиков, а pageScale() больше 1.0. В этом случае 'bottom' обнаруживается в координатном пространстве CSS и из-за округления может не всегда корректно отображаться в координатное пространство android.view.View (хотя это должно быть исправлено в KitKat).
- Вы или используемая вами библиотека переопределяете
WebView.scrollTo
/overScrollBy
/ и т.д.. чтобы не допустить прокрутки до самого конца.
В качестве последнего обходного пути вы можете переопределить 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;
}
Если это воспроизводится в новейшей версии Android, не могли бы вы подать отчет об ошибке. Идеально создать минималистичное приложение, которое воспроизводит проблему с пустой (или тривиальной) страницей.
Получил точный результат со следующим:
@Override
protected void onScrollChanged(int x, int y, int oldX, int oldY) {
super.onScrollChanged(x, y, oldX, oldY);
if (y == computeVerticalScrollRange() - getHeight()) {
// Trigger listener
}
}