From e6f5e24b5d145cb571f82b2e01178be4c3eff662 Mon Sep 17 00:00:00 2001 From: Robin Watts Date: Thu, 24 Jan 2013 17:32:56 +0000 Subject: Android: Refine Smart Motion to avoid tiny scrolls at end of pages Tor observes that when advancing down a page, it's annoying to have a tiny scroll at the end to expose the last pixel. To avoid this, he suggests making the amount we scroll dynamic; rather than always moving by 90% of the screen height, we allow ourselves to move between 80% and 95% of the screen height if it means that we'll exactly meet the end of the page. This seems to work well. --- android/src/com/artifex/mupdfdemo/ReaderView.java | 33 ++++++++++++++++++----- 1 file changed, 27 insertions(+), 6 deletions(-) (limited to 'android') diff --git a/android/src/com/artifex/mupdfdemo/ReaderView.java b/android/src/com/artifex/mupdfdemo/ReaderView.java index 4d84d03b..1ef8db70 100644 --- a/android/src/com/artifex/mupdfdemo/ReaderView.java +++ b/android/src/com/artifex/mupdfdemo/ReaderView.java @@ -105,6 +105,31 @@ public class ReaderView extends AdapterView slideViewOntoScreen(v); } + // When advancing down the page, we want to advance by about + // 90% of a screenful. But we'd be happy to advance by between + // 80% and 95% if it means we hit the bottom in a whole number + // of steps. + private int smartAdvanceAmount(int screenHeight, int max) { + int advance = (int)(screenHeight * 0.9 + 0.5); + int leftOver = max % advance; + int steps = max / advance; + if (leftOver == 0) { + // We'll make it exactly. No adjustment + } else if ((float)leftOver / steps <= screenHeight * 0.05) { + // We can adjust up by less than 5% to make it exact. + advance += (int)((float)leftOver/steps + 0.5); + } else { + int overshoot = advance - leftOver; + if ((float)overshoot / steps <= screenHeight * 0.1) { + // We can adjust down by less than 10% to make it exact. + advance -= (int)((float)overshoot/steps + 0.5); + } + } + if (advance > max) + advance = max; + return advance; + } + public void smartMoveForwards() { View v = mChildViews.get(mCurrent); if (v == null) @@ -171,9 +196,7 @@ public class ReaderView extends AdapterView } else { // Advance by 90% of the screen height downwards (in case lines are partially cut off) xOffset = 0; - yOffset = (int)(screenHeight * 0.9 + 0.5); - if (yOffset + bottom > docHeight) - yOffset = docHeight - bottom; + yOffset = smartAdvanceAmount(screenHeight, docHeight - bottom); } mScrollerLastX = mScrollerLastY = 0; mScroller.startScroll(0, 0, remainingX - xOffset, remainingY - yOffset, 400); @@ -246,9 +269,7 @@ public class ReaderView extends AdapterView } else { // Retreat by 90% of the screen height downwards (in case lines are partially cut off) xOffset = 0; - yOffset = - (int)(screenHeight * 0.9 + 0.5); - if (yOffset < -top) - yOffset = -top; + yOffset = -smartAdvanceAmount(screenHeight, top); } mScrollerLastX = mScrollerLastY = 0; mScroller.startScroll(0, 0, remainingX - xOffset, remainingY - yOffset, 400); -- cgit v1.2.3