Loading core/java/android/webkit/WebView.java +201 −27 Original line number Diff line number Diff line Loading @@ -16,13 +16,16 @@ package android.webkit; import com.android.internal.R; import android.annotation.Widget; import android.app.AlertDialog; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.DialogInterface.OnCancelListener; import android.content.Intent; import android.content.pm.PackageManager; import android.content.res.Resources; import android.database.DataSetObserver; import android.graphics.Bitmap; import android.graphics.BitmapFactory; Loading @@ -30,7 +33,6 @@ import android.graphics.BitmapShader; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Interpolator; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.Picture; import android.graphics.Point; Loading @@ -39,8 +41,8 @@ import android.graphics.RectF; import android.graphics.Region; import android.graphics.Shader; import android.graphics.drawable.Drawable; import android.net.http.SslCertificate; import android.net.Uri; import android.net.http.SslCertificate; import android.os.Bundle; import android.os.Handler; import android.os.Message; Loading Loading @@ -74,8 +76,10 @@ import android.webkit.WebViewCore.TouchEventData; import android.widget.AbsoluteLayout; import android.widget.Adapter; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.ArrayAdapter; import android.widget.CheckedTextView; import android.widget.EdgeGlow; import android.widget.FrameLayout; import android.widget.LinearLayout; import android.widget.ListView; Loading @@ -83,17 +87,15 @@ import android.widget.OverScroller; import android.widget.Toast; import android.widget.ZoomButtonsController; import android.widget.ZoomControls; import android.widget.AdapterView.OnItemClickListener; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.net.URLDecoder; import java.util.ArrayList; import java.util.List; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; Loading Loading @@ -757,6 +759,27 @@ public class WebView extends AbsoluteLayout private int mHorizontalScrollBarMode = SCROLLBAR_AUTO; private int mVerticalScrollBarMode = SCROLLBAR_AUTO; /** * Max distance to overscroll by in pixels. * This how far content can be pulled beyond its normal bounds by the user. */ private int mOverscrollDistance; /** * Max distance to overfling by in pixels. * This is how far flinged content can move beyond the end of its normal bounds. */ private int mOverflingDistance; /* * These manage the edge glow effect when flung or pulled beyond the edges. * If one is not null, all are not null. Checking one for null is as good as checking each. */ private EdgeGlow mEdgeGlowTop; private EdgeGlow mEdgeGlowBottom; private EdgeGlow mEdgeGlowLeft; private EdgeGlow mEdgeGlowRight; // Used to match key downs and key ups private boolean mGotKeyDown; Loading Loading @@ -986,7 +1009,6 @@ public class WebView extends AbsoluteLayout setFocusableInTouchMode(true); setClickable(true); setLongClickable(true); setOverscrollMode(OVERSCROLL_NEVER); final ViewConfiguration configuration = ViewConfiguration.get(getContext()); int slop = configuration.getScaledTouchSlop(); Loading @@ -1009,6 +1031,29 @@ public class WebView extends AbsoluteLayout mMaxZoomScale = DEFAULT_MAX_ZOOM_SCALE; mMinZoomScale = DEFAULT_MIN_ZOOM_SCALE; mMaximumFling = configuration.getScaledMaximumFlingVelocity(); mOverscrollDistance = configuration.getScaledOverscrollDistance(); mOverflingDistance = configuration.getScaledOverflingDistance(); } @Override public void setOverscrollMode(int mode) { super.setOverscrollMode(mode); if (mode != OVERSCROLL_NEVER) { if (mEdgeGlowTop == null) { final Resources res = getContext().getResources(); final Drawable edge = res.getDrawable(R.drawable.edge_light); final Drawable glow = res.getDrawable(R.drawable.overscroll_glow); mEdgeGlowTop = new EdgeGlow(edge, glow); mEdgeGlowBottom = new EdgeGlow(edge, glow); mEdgeGlowLeft = new EdgeGlow(edge, glow); mEdgeGlowRight = new EdgeGlow(edge, glow); } } else { mEdgeGlowTop = null; mEdgeGlowBottom = null; mEdgeGlowLeft = null; mEdgeGlowRight = null; } } /* package */void updateDefaultZoomDensity(int zoomDensity) { Loading Loading @@ -2500,6 +2545,9 @@ public class WebView extends AbsoluteLayout protected void onDrawVerticalScrollBar(Canvas canvas, Drawable scrollBar, int l, int t, int r, int b) { if (mScrollY < 0) { t -= mScrollY; } scrollBar.setBounds(l, t + getVisibleTitleHeight(), r, b); scrollBar.draw(canvas); } Loading @@ -2518,6 +2566,12 @@ public class WebView extends AbsoluteLayout if (scrollY < 0 || scrollY > computeMaxScrollY()) { mInOverScrollMode = true; } if ((clampedX && maxX > 0) || clampedY) { // Hitting a scroll barrier breaks velocity; don't fling further. mVelocityTracker.clear(); mLastVelocity = 0; } super.scrollTo(scrollX, scrollY); } Loading Loading @@ -2876,12 +2930,35 @@ public class WebView extends AbsoluteLayout int oldY = mScrollY; int x = mScroller.getCurrX(); int y = mScroller.getCurrY(); postInvalidate(); // So we draw again invalidate(); // So we draw again if (oldX != x || oldY != y) { final int rangeX = computeMaxScrollX(); final int rangeY = computeMaxScrollY(); overscrollBy(x - oldX, y - oldY, oldX, oldY, computeMaxScrollX(), computeMaxScrollY(), getViewWidth() / 3, getViewHeight() / 3, false); rangeX, rangeY, mOverflingDistance, mOverflingDistance, false); if (mEdgeGlowTop != null) { if (rangeY > 0 || getOverscrollMode() == OVERSCROLL_ALWAYS) { if (y < 0 && oldY >= 0) { mEdgeGlowTop.onAbsorb((int) mScroller.getCurrVelocity()); } else if (y > rangeY && oldY <= rangeY) { mEdgeGlowBottom.onAbsorb((int) mScroller.getCurrVelocity()); } } if (rangeX > 0) { if (x < 0 && oldX >= 0) { mEdgeGlowLeft.onAbsorb((int) mScroller.getCurrVelocity()); } else if (x > rangeX && oldX <= rangeX) { mEdgeGlowRight.onAbsorb((int) mScroller.getCurrVelocity()); } } } } if (mScroller.isFinished()) { mPrivateHandler.sendEmptyMessage(RESUME_WEBCORE_PRIORITY); } } else { super.computeScroll(); Loading Loading @@ -3292,13 +3369,8 @@ public class WebView extends AbsoluteLayout protected boolean drawChild(Canvas canvas, View child, long drawingTime) { if (child == mTitleBar) { // When drawing the title bar, move it horizontally to always show // at the top of the WebView. While overscroll, stick the title bar // on the top otherwise we may have two during loading, one is drawn // here, another is drawn by the Browser. // at the top of the WebView. mTitleBar.offsetLeftAndRight(mScrollX - mTitleBar.getLeft()); if (mScrollY <= 0) { mTitleBar.offsetTopAndBottom(mScrollY - mTitleBar.getTop()); } } return super.drawChild(canvas, child, drawingTime); } Loading Loading @@ -3349,7 +3421,7 @@ public class WebView extends AbsoluteLayout mOverScrollBorder.setColor(0xffbbbbbb); } int top = getTitleHeight(); int top = 0; int right = computeRealHorizontalScrollRange(); int bottom = top + computeRealVerticalScrollRange(); // first draw the background and anchor to the top of the view Loading Loading @@ -3389,12 +3461,72 @@ public class WebView extends AbsoluteLayout mScrollY + height); mTitleShadow.draw(canvas); } if (AUTO_REDRAW_HACK && mAutoRedraw) { invalidate(); } mWebViewCore.signalRepaintDone(); } @Override protected void dispatchDraw(Canvas canvas) { super.dispatchDraw(canvas); if (mEdgeGlowTop != null && drawEdgeGlows(canvas)) { invalidate(); } } /** * Draw the glow effect along the sides of the widget. mEdgeGlow* must be non-null. * * @param canvas Canvas to draw into, transformed into view coordinates. * @return true if glow effects are still animating and the view should invalidate again. */ private boolean drawEdgeGlows(Canvas canvas) { final int scrollX = mScrollX; final int scrollY = mScrollY; final int width = getWidth(); int height = getHeight(); boolean invalidateForGlow = false; if (!mEdgeGlowTop.isFinished()) { final int restoreCount = canvas.save(); canvas.translate(-width / 2 + scrollX, scrollY); mEdgeGlowTop.setSize(width * 2, height); invalidateForGlow |= mEdgeGlowTop.draw(canvas); canvas.restoreToCount(restoreCount); } if (!mEdgeGlowBottom.isFinished()) { final int restoreCount = canvas.save(); canvas.translate(-width / 2 - scrollX, scrollY + height); canvas.rotate(180, width, 0); mEdgeGlowBottom.setSize(width * 2, height); invalidateForGlow |= mEdgeGlowBottom.draw(canvas); canvas.restoreToCount(restoreCount); } if (!mEdgeGlowLeft.isFinished()) { final int restoreCount = canvas.save(); canvas.rotate(270); canvas.translate(-height * 1.5f - scrollY, scrollX); mEdgeGlowLeft.setSize(height * 2, width); invalidateForGlow |= mEdgeGlowLeft.draw(canvas); canvas.restoreToCount(restoreCount); } if (!mEdgeGlowRight.isFinished()) { final int restoreCount = canvas.save(); canvas.rotate(90); canvas.translate(-height / 2 + scrollY, -scrollX - width); mEdgeGlowRight.setSize(height * 2, width); invalidateForGlow |= mEdgeGlowRight.draw(canvas); canvas.restoreToCount(restoreCount); } return invalidateForGlow; } @Override public void setLayoutParams(ViewGroup.LayoutParams params) { if (params.height == LayoutParams.WRAP_CONTENT) { Loading Loading @@ -5386,9 +5518,34 @@ public class WebView extends AbsoluteLayout private void doDrag(int deltaX, int deltaY) { if ((deltaX | deltaY) != 0) { overscrollBy(deltaX, deltaY, mScrollX, mScrollY, computeMaxScrollX(), computeMaxScrollY(), getViewWidth() / 3, getViewHeight() / 3, true); final int oldX = mScrollX; final int oldY = mScrollY; final int rangeX = computeMaxScrollX(); final int rangeY = computeMaxScrollY(); overscrollBy(deltaX, deltaY, oldX, oldY, rangeX, rangeY, mOverscrollDistance, mOverscrollDistance, true); if (mEdgeGlowTop != null) { // Don't show left/right glows if we fit the whole content. if (rangeX > 0) { final int pulledToX = oldX + deltaX; if (pulledToX < 0) { mEdgeGlowLeft.onPull((float) deltaX / getWidth()); } else if (pulledToX > rangeX) { mEdgeGlowRight.onPull((float) deltaX / getWidth()); } } if (rangeY > 0 || getOverscrollMode() == OVERSCROLL_ALWAYS) { final int pulledToY = oldY + deltaY; if (pulledToY < 0) { mEdgeGlowTop.onPull((float) deltaY / getHeight()); } else if (pulledToY > rangeY) { mEdgeGlowBottom.onPull((float) deltaY / getHeight()); } } } } if (!getSettings().getBuiltInZoomControls()) { boolean showPlusMinus = mMinZoomScale < mMaxZoomScale; Loading @@ -5415,6 +5572,14 @@ public class WebView extends AbsoluteLayout mVelocityTracker.recycle(); mVelocityTracker = null; } // Release any pulled glows if (mEdgeGlowTop != null) { mEdgeGlowTop.onRelease(); mEdgeGlowBottom.onRelease(); mEdgeGlowLeft.onRelease(); mEdgeGlowRight.onRelease(); } } private void cancelTouch() { Loading @@ -5428,6 +5593,15 @@ public class WebView extends AbsoluteLayout mVelocityTracker.recycle(); mVelocityTracker = null; } // Release any pulled glows if (mEdgeGlowTop != null) { mEdgeGlowTop.onRelease(); mEdgeGlowBottom.onRelease(); mEdgeGlowLeft.onRelease(); mEdgeGlowRight.onRelease(); } if (mTouchMode == TOUCH_DRAG_MODE) { WebViewCore.resumePriority(); WebViewCore.resumeUpdatePicture(mWebViewCore); Loading Loading @@ -5746,7 +5920,7 @@ public class WebView extends AbsoluteLayout public void flingScroll(int vx, int vy) { mScroller.fling(mScrollX, mScrollY, vx, vy, 0, computeMaxScrollX(), 0, computeMaxScrollY(), getViewWidth() / 3, getViewHeight() / 3); computeMaxScrollY(), mOverflingDistance, mOverflingDistance); invalidate(); } Loading Loading @@ -5809,13 +5983,13 @@ public class WebView extends AbsoluteLayout // no horizontal overscroll if the content just fits mScroller.fling(mScrollX, mScrollY, -vx, -vy, 0, maxX, 0, maxY, maxX == 0 ? 0 : getViewWidth() / 3, getViewHeight() / 3); // TODO: duration is calculated based on velocity, if the range is // small, the animation will stop before duration is up. We may // want to calculate how long the animation is going to run to precisely // resume the webcore update. maxX == 0 ? 0 : mOverflingDistance, mOverflingDistance); // Duration is calculated based on velocity. With range boundaries and overscroll // we may not know how long the final animation will take. (Hence the deprecation // warning on the call below.) It's not a big deal for scroll bars but if webcore // resumes during this effect we will take a performance hit. See computeScroll; // we resume webcore there when the animation is finished. final int time = mScroller.getDuration(); mPrivateHandler.sendEmptyMessageDelayed(RESUME_WEBCORE_PRIORITY, time); awakenScrollBars(time); invalidate(); } Loading core/java/android/widget/EdgeGlow.java +1 −1 Original line number Diff line number Diff line Loading @@ -213,7 +213,7 @@ public class EdgeGlow { final int glowHeight = mGlow.getIntrinsicHeight(); mGlow.setAlpha((int) (Math.max(0, Math.min(mGlowAlpha, 1)) * 255)); mGlow.setBounds(0, 0, mWidth, (int) (glowHeight * mGlowScaleY)); mGlow.setBounds(0, 0, mWidth, (int) (glowHeight * mGlowScaleY * 0.5f)); mGlow.draw(canvas); mEdge.setAlpha((int) (Math.max(0, Math.min(mEdgeAlpha, 1)) * 255)); Loading core/java/android/widget/OverScroller.java +1 −1 Original line number Diff line number Diff line Loading @@ -523,7 +523,7 @@ public class OverScroller { // If the velocity is smaller than this value, no bounce is triggered // when the edge limits are reached (would result in a zero pixels // displacement anyway). private static final float MINIMUM_VELOCITY_FOR_BOUNCE = 140.0f; private static final float MINIMUM_VELOCITY_FOR_BOUNCE = Float.MAX_VALUE;//140.0f; // Proportion of the velocity that is preserved when the edge is reached. private static final float DEFAULT_BOUNCE_COEFFICIENT = 0.16f; Loading Loading
core/java/android/webkit/WebView.java +201 −27 Original line number Diff line number Diff line Loading @@ -16,13 +16,16 @@ package android.webkit; import com.android.internal.R; import android.annotation.Widget; import android.app.AlertDialog; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.DialogInterface.OnCancelListener; import android.content.Intent; import android.content.pm.PackageManager; import android.content.res.Resources; import android.database.DataSetObserver; import android.graphics.Bitmap; import android.graphics.BitmapFactory; Loading @@ -30,7 +33,6 @@ import android.graphics.BitmapShader; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Interpolator; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.Picture; import android.graphics.Point; Loading @@ -39,8 +41,8 @@ import android.graphics.RectF; import android.graphics.Region; import android.graphics.Shader; import android.graphics.drawable.Drawable; import android.net.http.SslCertificate; import android.net.Uri; import android.net.http.SslCertificate; import android.os.Bundle; import android.os.Handler; import android.os.Message; Loading Loading @@ -74,8 +76,10 @@ import android.webkit.WebViewCore.TouchEventData; import android.widget.AbsoluteLayout; import android.widget.Adapter; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.ArrayAdapter; import android.widget.CheckedTextView; import android.widget.EdgeGlow; import android.widget.FrameLayout; import android.widget.LinearLayout; import android.widget.ListView; Loading @@ -83,17 +87,15 @@ import android.widget.OverScroller; import android.widget.Toast; import android.widget.ZoomButtonsController; import android.widget.ZoomControls; import android.widget.AdapterView.OnItemClickListener; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.net.URLDecoder; import java.util.ArrayList; import java.util.List; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; Loading Loading @@ -757,6 +759,27 @@ public class WebView extends AbsoluteLayout private int mHorizontalScrollBarMode = SCROLLBAR_AUTO; private int mVerticalScrollBarMode = SCROLLBAR_AUTO; /** * Max distance to overscroll by in pixels. * This how far content can be pulled beyond its normal bounds by the user. */ private int mOverscrollDistance; /** * Max distance to overfling by in pixels. * This is how far flinged content can move beyond the end of its normal bounds. */ private int mOverflingDistance; /* * These manage the edge glow effect when flung or pulled beyond the edges. * If one is not null, all are not null. Checking one for null is as good as checking each. */ private EdgeGlow mEdgeGlowTop; private EdgeGlow mEdgeGlowBottom; private EdgeGlow mEdgeGlowLeft; private EdgeGlow mEdgeGlowRight; // Used to match key downs and key ups private boolean mGotKeyDown; Loading Loading @@ -986,7 +1009,6 @@ public class WebView extends AbsoluteLayout setFocusableInTouchMode(true); setClickable(true); setLongClickable(true); setOverscrollMode(OVERSCROLL_NEVER); final ViewConfiguration configuration = ViewConfiguration.get(getContext()); int slop = configuration.getScaledTouchSlop(); Loading @@ -1009,6 +1031,29 @@ public class WebView extends AbsoluteLayout mMaxZoomScale = DEFAULT_MAX_ZOOM_SCALE; mMinZoomScale = DEFAULT_MIN_ZOOM_SCALE; mMaximumFling = configuration.getScaledMaximumFlingVelocity(); mOverscrollDistance = configuration.getScaledOverscrollDistance(); mOverflingDistance = configuration.getScaledOverflingDistance(); } @Override public void setOverscrollMode(int mode) { super.setOverscrollMode(mode); if (mode != OVERSCROLL_NEVER) { if (mEdgeGlowTop == null) { final Resources res = getContext().getResources(); final Drawable edge = res.getDrawable(R.drawable.edge_light); final Drawable glow = res.getDrawable(R.drawable.overscroll_glow); mEdgeGlowTop = new EdgeGlow(edge, glow); mEdgeGlowBottom = new EdgeGlow(edge, glow); mEdgeGlowLeft = new EdgeGlow(edge, glow); mEdgeGlowRight = new EdgeGlow(edge, glow); } } else { mEdgeGlowTop = null; mEdgeGlowBottom = null; mEdgeGlowLeft = null; mEdgeGlowRight = null; } } /* package */void updateDefaultZoomDensity(int zoomDensity) { Loading Loading @@ -2500,6 +2545,9 @@ public class WebView extends AbsoluteLayout protected void onDrawVerticalScrollBar(Canvas canvas, Drawable scrollBar, int l, int t, int r, int b) { if (mScrollY < 0) { t -= mScrollY; } scrollBar.setBounds(l, t + getVisibleTitleHeight(), r, b); scrollBar.draw(canvas); } Loading @@ -2518,6 +2566,12 @@ public class WebView extends AbsoluteLayout if (scrollY < 0 || scrollY > computeMaxScrollY()) { mInOverScrollMode = true; } if ((clampedX && maxX > 0) || clampedY) { // Hitting a scroll barrier breaks velocity; don't fling further. mVelocityTracker.clear(); mLastVelocity = 0; } super.scrollTo(scrollX, scrollY); } Loading Loading @@ -2876,12 +2930,35 @@ public class WebView extends AbsoluteLayout int oldY = mScrollY; int x = mScroller.getCurrX(); int y = mScroller.getCurrY(); postInvalidate(); // So we draw again invalidate(); // So we draw again if (oldX != x || oldY != y) { final int rangeX = computeMaxScrollX(); final int rangeY = computeMaxScrollY(); overscrollBy(x - oldX, y - oldY, oldX, oldY, computeMaxScrollX(), computeMaxScrollY(), getViewWidth() / 3, getViewHeight() / 3, false); rangeX, rangeY, mOverflingDistance, mOverflingDistance, false); if (mEdgeGlowTop != null) { if (rangeY > 0 || getOverscrollMode() == OVERSCROLL_ALWAYS) { if (y < 0 && oldY >= 0) { mEdgeGlowTop.onAbsorb((int) mScroller.getCurrVelocity()); } else if (y > rangeY && oldY <= rangeY) { mEdgeGlowBottom.onAbsorb((int) mScroller.getCurrVelocity()); } } if (rangeX > 0) { if (x < 0 && oldX >= 0) { mEdgeGlowLeft.onAbsorb((int) mScroller.getCurrVelocity()); } else if (x > rangeX && oldX <= rangeX) { mEdgeGlowRight.onAbsorb((int) mScroller.getCurrVelocity()); } } } } if (mScroller.isFinished()) { mPrivateHandler.sendEmptyMessage(RESUME_WEBCORE_PRIORITY); } } else { super.computeScroll(); Loading Loading @@ -3292,13 +3369,8 @@ public class WebView extends AbsoluteLayout protected boolean drawChild(Canvas canvas, View child, long drawingTime) { if (child == mTitleBar) { // When drawing the title bar, move it horizontally to always show // at the top of the WebView. While overscroll, stick the title bar // on the top otherwise we may have two during loading, one is drawn // here, another is drawn by the Browser. // at the top of the WebView. mTitleBar.offsetLeftAndRight(mScrollX - mTitleBar.getLeft()); if (mScrollY <= 0) { mTitleBar.offsetTopAndBottom(mScrollY - mTitleBar.getTop()); } } return super.drawChild(canvas, child, drawingTime); } Loading Loading @@ -3349,7 +3421,7 @@ public class WebView extends AbsoluteLayout mOverScrollBorder.setColor(0xffbbbbbb); } int top = getTitleHeight(); int top = 0; int right = computeRealHorizontalScrollRange(); int bottom = top + computeRealVerticalScrollRange(); // first draw the background and anchor to the top of the view Loading Loading @@ -3389,12 +3461,72 @@ public class WebView extends AbsoluteLayout mScrollY + height); mTitleShadow.draw(canvas); } if (AUTO_REDRAW_HACK && mAutoRedraw) { invalidate(); } mWebViewCore.signalRepaintDone(); } @Override protected void dispatchDraw(Canvas canvas) { super.dispatchDraw(canvas); if (mEdgeGlowTop != null && drawEdgeGlows(canvas)) { invalidate(); } } /** * Draw the glow effect along the sides of the widget. mEdgeGlow* must be non-null. * * @param canvas Canvas to draw into, transformed into view coordinates. * @return true if glow effects are still animating and the view should invalidate again. */ private boolean drawEdgeGlows(Canvas canvas) { final int scrollX = mScrollX; final int scrollY = mScrollY; final int width = getWidth(); int height = getHeight(); boolean invalidateForGlow = false; if (!mEdgeGlowTop.isFinished()) { final int restoreCount = canvas.save(); canvas.translate(-width / 2 + scrollX, scrollY); mEdgeGlowTop.setSize(width * 2, height); invalidateForGlow |= mEdgeGlowTop.draw(canvas); canvas.restoreToCount(restoreCount); } if (!mEdgeGlowBottom.isFinished()) { final int restoreCount = canvas.save(); canvas.translate(-width / 2 - scrollX, scrollY + height); canvas.rotate(180, width, 0); mEdgeGlowBottom.setSize(width * 2, height); invalidateForGlow |= mEdgeGlowBottom.draw(canvas); canvas.restoreToCount(restoreCount); } if (!mEdgeGlowLeft.isFinished()) { final int restoreCount = canvas.save(); canvas.rotate(270); canvas.translate(-height * 1.5f - scrollY, scrollX); mEdgeGlowLeft.setSize(height * 2, width); invalidateForGlow |= mEdgeGlowLeft.draw(canvas); canvas.restoreToCount(restoreCount); } if (!mEdgeGlowRight.isFinished()) { final int restoreCount = canvas.save(); canvas.rotate(90); canvas.translate(-height / 2 + scrollY, -scrollX - width); mEdgeGlowRight.setSize(height * 2, width); invalidateForGlow |= mEdgeGlowRight.draw(canvas); canvas.restoreToCount(restoreCount); } return invalidateForGlow; } @Override public void setLayoutParams(ViewGroup.LayoutParams params) { if (params.height == LayoutParams.WRAP_CONTENT) { Loading Loading @@ -5386,9 +5518,34 @@ public class WebView extends AbsoluteLayout private void doDrag(int deltaX, int deltaY) { if ((deltaX | deltaY) != 0) { overscrollBy(deltaX, deltaY, mScrollX, mScrollY, computeMaxScrollX(), computeMaxScrollY(), getViewWidth() / 3, getViewHeight() / 3, true); final int oldX = mScrollX; final int oldY = mScrollY; final int rangeX = computeMaxScrollX(); final int rangeY = computeMaxScrollY(); overscrollBy(deltaX, deltaY, oldX, oldY, rangeX, rangeY, mOverscrollDistance, mOverscrollDistance, true); if (mEdgeGlowTop != null) { // Don't show left/right glows if we fit the whole content. if (rangeX > 0) { final int pulledToX = oldX + deltaX; if (pulledToX < 0) { mEdgeGlowLeft.onPull((float) deltaX / getWidth()); } else if (pulledToX > rangeX) { mEdgeGlowRight.onPull((float) deltaX / getWidth()); } } if (rangeY > 0 || getOverscrollMode() == OVERSCROLL_ALWAYS) { final int pulledToY = oldY + deltaY; if (pulledToY < 0) { mEdgeGlowTop.onPull((float) deltaY / getHeight()); } else if (pulledToY > rangeY) { mEdgeGlowBottom.onPull((float) deltaY / getHeight()); } } } } if (!getSettings().getBuiltInZoomControls()) { boolean showPlusMinus = mMinZoomScale < mMaxZoomScale; Loading @@ -5415,6 +5572,14 @@ public class WebView extends AbsoluteLayout mVelocityTracker.recycle(); mVelocityTracker = null; } // Release any pulled glows if (mEdgeGlowTop != null) { mEdgeGlowTop.onRelease(); mEdgeGlowBottom.onRelease(); mEdgeGlowLeft.onRelease(); mEdgeGlowRight.onRelease(); } } private void cancelTouch() { Loading @@ -5428,6 +5593,15 @@ public class WebView extends AbsoluteLayout mVelocityTracker.recycle(); mVelocityTracker = null; } // Release any pulled glows if (mEdgeGlowTop != null) { mEdgeGlowTop.onRelease(); mEdgeGlowBottom.onRelease(); mEdgeGlowLeft.onRelease(); mEdgeGlowRight.onRelease(); } if (mTouchMode == TOUCH_DRAG_MODE) { WebViewCore.resumePriority(); WebViewCore.resumeUpdatePicture(mWebViewCore); Loading Loading @@ -5746,7 +5920,7 @@ public class WebView extends AbsoluteLayout public void flingScroll(int vx, int vy) { mScroller.fling(mScrollX, mScrollY, vx, vy, 0, computeMaxScrollX(), 0, computeMaxScrollY(), getViewWidth() / 3, getViewHeight() / 3); computeMaxScrollY(), mOverflingDistance, mOverflingDistance); invalidate(); } Loading Loading @@ -5809,13 +5983,13 @@ public class WebView extends AbsoluteLayout // no horizontal overscroll if the content just fits mScroller.fling(mScrollX, mScrollY, -vx, -vy, 0, maxX, 0, maxY, maxX == 0 ? 0 : getViewWidth() / 3, getViewHeight() / 3); // TODO: duration is calculated based on velocity, if the range is // small, the animation will stop before duration is up. We may // want to calculate how long the animation is going to run to precisely // resume the webcore update. maxX == 0 ? 0 : mOverflingDistance, mOverflingDistance); // Duration is calculated based on velocity. With range boundaries and overscroll // we may not know how long the final animation will take. (Hence the deprecation // warning on the call below.) It's not a big deal for scroll bars but if webcore // resumes during this effect we will take a performance hit. See computeScroll; // we resume webcore there when the animation is finished. final int time = mScroller.getDuration(); mPrivateHandler.sendEmptyMessageDelayed(RESUME_WEBCORE_PRIORITY, time); awakenScrollBars(time); invalidate(); } Loading
core/java/android/widget/EdgeGlow.java +1 −1 Original line number Diff line number Diff line Loading @@ -213,7 +213,7 @@ public class EdgeGlow { final int glowHeight = mGlow.getIntrinsicHeight(); mGlow.setAlpha((int) (Math.max(0, Math.min(mGlowAlpha, 1)) * 255)); mGlow.setBounds(0, 0, mWidth, (int) (glowHeight * mGlowScaleY)); mGlow.setBounds(0, 0, mWidth, (int) (glowHeight * mGlowScaleY * 0.5f)); mGlow.draw(canvas); mEdge.setAlpha((int) (Math.max(0, Math.min(mEdgeAlpha, 1)) * 255)); Loading
core/java/android/widget/OverScroller.java +1 −1 Original line number Diff line number Diff line Loading @@ -523,7 +523,7 @@ public class OverScroller { // If the velocity is smaller than this value, no bounce is triggered // when the edge limits are reached (would result in a zero pixels // displacement anyway). private static final float MINIMUM_VELOCITY_FOR_BOUNCE = 140.0f; private static final float MINIMUM_VELOCITY_FOR_BOUNCE = Float.MAX_VALUE;//140.0f; // Proportion of the velocity that is preserved when the edge is reached. private static final float DEFAULT_BOUNCE_COEFFICIENT = 0.16f; Loading