also expose onDrawHorizontalScrollBar() in View
retool WebView's calculations to correctly compute scrollbar height and parameters
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 82bff4a..2f17bbc 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -5343,12 +5343,36 @@
size = cache.scrollBarSize;
}
+ final int scrollX = mScrollX;
+ final int scrollY = mScrollY;
+ final int inside = (viewFlags & SCROLLBARS_OUTSIDE_MASK) == 0 ? ~0 : 0;
+
if (drawHorizontalScrollBar) {
- onDrawHorizontalScrollBar(canvas, scrollBar, width, height, size);
+ scrollBar.setParameters(
+ computeHorizontalScrollRange(),
+ computeHorizontalScrollOffset(),
+ computeHorizontalScrollExtent(), false);
+ final int top = scrollY + height - size - (mUserPaddingBottom & inside);
+ final int verticalScrollBarGap = drawVerticalScrollBar ?
+ getVerticalScrollbarWidth() : 0;
+ onDrawHorizontalScrollBar(canvas, scrollBar,
+ scrollX + (mPaddingLeft & inside),
+ top,
+ scrollX + width - (mUserPaddingRight & inside) - verticalScrollBarGap,
+ top + size);
}
if (drawVerticalScrollBar) {
- onDrawVerticalScrollBar(canvas, scrollBar, width, height, size);
+ scrollBar.setParameters(computeVerticalScrollRange(),
+ computeVerticalScrollOffset(),
+ computeVerticalScrollExtent(), true);
+ // TODO: Deal with RTL languages to position scrollbar on left
+ final int left = scrollX + width - size - (mUserPaddingRight & inside);
+ onDrawVerticalScrollBar(canvas, scrollBar,
+ left,
+ scrollY + (mPaddingTop & inside),
+ left + size,
+ scrollY + height - (mUserPaddingBottom & inside));
}
}
}
@@ -5368,96 +5392,42 @@
* <p>Draw the horizontal scrollbar if
* {@link #isHorizontalScrollBarEnabled()} returns true.</p>
*
- * <p>The length of the scrollbar and its thumb is computed according to the
- * values returned by {@link #computeHorizontalScrollRange()},
- * {@link #computeHorizontalScrollExtent()} and
- * {@link #computeHorizontalScrollOffset()}. Refer to
- * {@link android.widget.ScrollBarDrawable} for more information about how
- * these values relate to each other.</p>
- *
* @param canvas the canvas on which to draw the scrollbar
* @param scrollBar the scrollbar's drawable
- * @param width the width of the drawing surface
- * @param height the height of the drawing surface
- * @param size the size of the scrollbar
*
* @see #isHorizontalScrollBarEnabled()
* @see #computeHorizontalScrollRange()
* @see #computeHorizontalScrollExtent()
* @see #computeHorizontalScrollOffset()
* @see android.widget.ScrollBarDrawable
- */
- private void onDrawHorizontalScrollBar(Canvas canvas, ScrollBarDrawable scrollBar, int width,
- int height, int size) {
-
- final int viewFlags = mViewFlags;
- final int scrollX = mScrollX;
- final int scrollY = mScrollY;
- final int inside = (viewFlags & SCROLLBARS_OUTSIDE_MASK) == 0 ? ~0 : 0;
- final int top = scrollY + height - size - (mUserPaddingBottom & inside);
-
- final int verticalScrollBarGap =
- (viewFlags & SCROLLBARS_VERTICAL) == SCROLLBARS_VERTICAL ?
- getVerticalScrollbarWidth() : 0;
-
- scrollBar.setBounds(scrollX + (mPaddingLeft & inside), top,
- scrollX + width - (mUserPaddingRight & inside) - verticalScrollBarGap, top + size);
- scrollBar.setParameters(
- computeHorizontalScrollRange(),
- computeHorizontalScrollOffset(),
- computeHorizontalScrollExtent(), false);
- scrollBar.draw(canvas);
- }
-
- /**
* @hide
*/
- protected void onDrawVScrollBar(Canvas canvas, ScrollBarDrawable scrollBar,
- int l, int t, int r, int b) {
+ protected void onDrawHorizontalScrollBar(Canvas canvas,
+ Drawable scrollBar,
+ int l, int t, int r, int b) {
scrollBar.setBounds(l, t, r, b);
- scrollBar.setParameters(computeVerticalScrollRange(),
- computeVerticalScrollOffset(),
- computeVerticalScrollExtent(), true);
scrollBar.draw(canvas);
}
-
+
/**
* <p>Draw the vertical scrollbar if {@link #isVerticalScrollBarEnabled()}
* returns true.</p>
*
- * <p>The length of the scrollbar and its thumb is computed according to the
- * values returned by {@link #computeVerticalScrollRange()},
- * {@link #computeVerticalScrollExtent()} and
- * {@link #computeVerticalScrollOffset()}. Refer to
- * {@link android.widget.ScrollBarDrawable} for more information about how
- * these values relate to each other.</p>
- *
* @param canvas the canvas on which to draw the scrollbar
* @param scrollBar the scrollbar's drawable
- * @param width the width of the drawing surface
- * @param height the height of the drawing surface
- * @param size the size of the scrollbar
*
* @see #isVerticalScrollBarEnabled()
* @see #computeVerticalScrollRange()
* @see #computeVerticalScrollExtent()
* @see #computeVerticalScrollOffset()
* @see android.widget.ScrollBarDrawable
+ * @hide
*/
- private void onDrawVerticalScrollBar(Canvas canvas, ScrollBarDrawable scrollBar, int width,
- int height, int size) {
-
- final int scrollX = mScrollX;
- final int scrollY = mScrollY;
- final int inside = (mViewFlags & SCROLLBARS_OUTSIDE_MASK) == 0 ? ~0 : 0;
- // TODO: Deal with RTL languages to position scrollbar on left
- final int left = scrollX + width - size - (mUserPaddingRight & inside);
-
- onDrawVScrollBar(canvas, scrollBar,
- left,
- scrollY + (mPaddingTop & inside),
- left + size,
- scrollY + height - (mUserPaddingBottom & inside));
+ protected void onDrawVerticalScrollBar(Canvas canvas,
+ Drawable scrollBar,
+ int l, int t, int r, int b) {
+ scrollBar.setBounds(l, t, r, b);
+ scrollBar.draw(canvas);
}
/**
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index d0e66ee..0416c64 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -31,6 +31,7 @@
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.Region;
+import android.graphics.drawable.Drawable;
import android.net.http.SslCertificate;
import android.net.Uri;
import android.os.Bundle;
@@ -67,6 +68,7 @@
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.ListView;
+import android.widget.ScrollBarDrawable;
import android.widget.Scroller;
import android.widget.Toast;
import android.widget.ZoomButtonsController;
@@ -937,21 +939,30 @@
}
/*
+ * returns the height of the titlebarview (if any). Does not care about
+ * scrolling
+ */
+ private int getTitleHeight() {
+ return mTitleBar != null ? mTitleBar.getHeight() : 0;
+ }
+
+ /*
+ * Return the amount of the titlebarview (if any) that is visible
+ */
+ private int getVisibleTitleHeight() {
+ return Math.max(getTitleHeight() - mScrollY, 0);
+ }
+
+ /*
* Return the height of the view where the content of WebView should render
* to. Note that this excludes mTitleBar, if there is one.
*/
private int getViewHeight() {
int height = getHeight();
- if (isHorizontalScrollBarEnabled() && mOverlayHorizontalScrollbar) {
+ if (isHorizontalScrollBarEnabled() && !mOverlayHorizontalScrollbar) {
height -= getHorizontalScrollbarHeight();
}
- if (mTitleBar != null) {
- int titleBarVisibleHeight = mTitleBar.getHeight() - mScrollY;
- if (titleBarVisibleHeight > 0) {
- height -= titleBarVisibleHeight;
- }
- }
- return height;
+ return height - getVisibleTitleHeight();
}
/**
@@ -1741,7 +1752,15 @@
// Expects y in view coordinates
private int pinLocY(int y) {
- return pinLoc(y, getViewHeight(), computeVerticalScrollRange());
+ int titleH = getTitleHeight();
+ // if the titlebar is still visible, just pin against 0
+ if (y <= titleH) {
+ return Math.max(y, 0);
+ }
+ // convert to 0-based coordinate (subtract the title height)
+ // pin(), and then add the title height back in
+ return pinLoc(y - titleH, getViewHeight(),
+ computeVerticalScrollRange()) + titleH;
}
/**
@@ -1783,10 +1802,17 @@
* embedded into the WebView.
*/
/*package*/ int viewToContentY(int y) {
- if (mTitleBar != null) {
- y -= mTitleBar.getHeight();
- }
- return viewToContentX(y);
+ return viewToContentX(y - getTitleHeight());
+ }
+
+ /**
+ * Given a distance in content space, convert it to view space. Note: this
+ * does not reflect translation, just scaling, so this should not be called
+ * with coordinates, but should be called for dimensions like width or
+ * height.
+ */
+ /*package*/ int contentToViewDimension(int d) {
+ return Math.round(d * mActualScale);
}
/**
@@ -1794,7 +1820,7 @@
* space. Also used for absolute heights.
*/
/*package*/ int contentToViewX(int x) {
- return Math.round(x * mActualScale);
+ return contentToViewDimension(x);
}
/**
@@ -1802,11 +1828,7 @@
* space. Takes into account the height of the title bar.
*/
/*package*/ int contentToViewY(int y) {
- int val = Math.round(y * mActualScale);
- if (mTitleBar != null) {
- val += mTitleBar.getHeight();
- }
- return val;
+ return contentToViewDimension(y) + getTitleHeight();
}
// Called by JNI to invalidate the View, given rectangle coordinates in
@@ -2024,7 +2046,7 @@
if (mDrawHistory) {
return mHistoryWidth;
} else {
- return contentToViewX(mContentWidth);
+ return contentToViewDimension(mContentWidth);
}
}
@@ -2036,7 +2058,7 @@
if (mDrawHistory) {
return mHistoryHeight;
} else {
- int height = contentToViewX(mContentHeight);
+ int height = contentToViewDimension(mContentHeight);
if (mFindIsUp) {
height += FIND_HEIGHT;
}
@@ -2046,14 +2068,7 @@
@Override
protected int computeVerticalScrollOffset() {
- int offset = super.computeVerticalScrollOffset();
- if (mTitleBar != null) {
- // Need to adjust so that the resulting offset is at minimum
- // the height of the title bar, if it is visible.
- offset += mTitleBar.getHeight()*computeVerticalScrollRange()
- /getViewHeight();
- }
- return offset;
+ return Math.max(mScrollY - getTitleHeight(), 0);
}
@Override
@@ -2061,6 +2076,15 @@
return getViewHeight();
}
+ /** @hide */
+ @Override
+ protected void onDrawVerticalScrollBar(Canvas canvas,
+ Drawable scrollBar,
+ int l, int t, int r, int b) {
+ scrollBar.setBounds(l, t + getVisibleTitleHeight(), r, b);
+ scrollBar.draw(canvas);
+ }
+
/**
* Get the url for the current page. This is not always the same as the url
* passed to WebViewClient.onPageStarted because although the load for
@@ -2412,8 +2436,8 @@
// keys are hit, this should be safe. Right?
return false;
}
- cx = contentToViewX(cx);
- cy = contentToViewY(cy);
+ cx = contentToViewDimension(cx);
+ cy = contentToViewDimension(cy);
if (mHeightCanMeasure) {
// move our visible rect according to scroll request
if (cy != 0) {
@@ -2482,12 +2506,12 @@
}
if (mHeightCanMeasure) {
- if (getMeasuredHeight() != contentToViewX(mContentHeight)
+ if (getMeasuredHeight() != contentToViewDimension(mContentHeight)
&& updateLayout) {
requestLayout();
}
} else if (mWidthCanMeasure) {
- if (getMeasuredWidth() != contentToViewX(mContentWidth)
+ if (getMeasuredWidth() != contentToViewDimension(mContentWidth)
&& updateLayout) {
requestLayout();
}
@@ -3272,7 +3296,7 @@
// Initialize our generation number.
mTextGeneration = 0;
}
- mWebTextView.setTextSize(contentToViewX(nativeFocusCandidateTextSize()));
+ mWebTextView.setTextSize(contentToViewDimension(nativeFocusCandidateTextSize()));
Rect visibleRect = new Rect();
calcOurContentVisibleRect(visibleRect);
// Note that sendOurVisibleRect calls viewToContent, so the coordinates
@@ -4506,9 +4530,15 @@
}
}
+ private int computeMaxScrollY() {
+ int maxContentH = contentToViewDimension(mContentHeight)
+ + getTitleHeight();
+ return Math.max(maxContentH - getHeight(), 0);
+ }
+
public void flingScroll(int vx, int vy) {
int maxX = Math.max(computeHorizontalScrollRange() - getViewWidth(), 0);
- int maxY = Math.max(computeVerticalScrollRange() - getViewHeight(), 0);
+ int maxY = computeMaxScrollY();
mScroller.fling(mScrollX, mScrollY, vx, vy, 0, maxX, 0, maxY);
invalidate();
@@ -4519,7 +4549,7 @@
return;
}
int maxX = Math.max(computeHorizontalScrollRange() - getViewWidth(), 0);
- int maxY = Math.max(computeVerticalScrollRange() - getViewHeight(), 0);
+ int maxY = computeMaxScrollY();
mVelocityTracker.computeCurrentVelocity(1000, mMaximumFling);
int vx = (int) mVelocityTracker.getXVelocity();