Per designers, update the algorithm for when effect is clipped or stretched.
New algo is: 1) if view width < MIN_WIDTH (currently 300px), clip glow and edge to fit 2) else stretch glow and edge to fill width 3) make alpha and height of edge and glow 30% "more intense" Change-Id: I8f121bb165a8fb835bc33950dbedd1bc80c5df65
This commit is contained in:
@ -17,6 +17,7 @@ package android.webkit;
|
||||
|
||||
import com.android.internal.R;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.drawable.Drawable;
|
||||
@ -40,13 +41,14 @@ public class OverScrollGlow {
|
||||
|
||||
public OverScrollGlow(WebView host) {
|
||||
mHostView = host;
|
||||
final Resources res = host.getContext().getResources();
|
||||
Context context = host.getContext();
|
||||
final Resources res = context.getResources();
|
||||
final Drawable edge = res.getDrawable(R.drawable.overscroll_edge);
|
||||
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);
|
||||
mEdgeGlowTop = new EdgeGlow(context, edge, glow);
|
||||
mEdgeGlowBottom = new EdgeGlow(context, edge, glow);
|
||||
mEdgeGlowLeft = new EdgeGlow(context, edge, glow);
|
||||
mEdgeGlowRight = new EdgeGlow(context, edge, glow);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -132,7 +132,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
|
||||
* Indicates the touch gesture is a scroll
|
||||
*/
|
||||
static final int TOUCH_MODE_SCROLL = 3;
|
||||
|
||||
|
||||
/**
|
||||
* Indicates the view is in the process of being flung
|
||||
*/
|
||||
@ -385,7 +385,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
|
||||
* Handles one frame of a fling
|
||||
*/
|
||||
private FlingRunnable mFlingRunnable;
|
||||
|
||||
|
||||
/**
|
||||
* Handles scrolling between positions within the list.
|
||||
*/
|
||||
@ -456,7 +456,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
|
||||
int mResurrectToPosition = INVALID_POSITION;
|
||||
|
||||
private ContextMenuInfo mContextMenuInfo = null;
|
||||
|
||||
|
||||
/**
|
||||
* Maximum distance to record overscroll
|
||||
*/
|
||||
@ -550,19 +550,19 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
|
||||
private int mMinimumVelocity;
|
||||
private int mMaximumVelocity;
|
||||
private float mVelocityScale = 1.0f;
|
||||
|
||||
|
||||
final boolean[] mIsScrap = new boolean[1];
|
||||
|
||||
|
||||
// True when the popup should be hidden because of a call to
|
||||
// dispatchDisplayHint()
|
||||
private boolean mPopupHidden;
|
||||
|
||||
|
||||
/**
|
||||
* ID of the active pointer. This is used to retain consistency during
|
||||
* drags/flings if multiple pointers are used.
|
||||
*/
|
||||
private int mActivePointerId = INVALID_POINTER;
|
||||
|
||||
|
||||
/**
|
||||
* Sentinel value for no current active pointer.
|
||||
* Used by {@link #mActivePointerId}.
|
||||
@ -726,7 +726,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
|
||||
|
||||
boolean smoothScrollbar = a.getBoolean(R.styleable.AbsListView_smoothScrollbar, true);
|
||||
setSmoothScrollbarEnabled(smoothScrollbar);
|
||||
|
||||
|
||||
final int adapterId = a.getResourceId(R.styleable.AbsListView_adapter, 0);
|
||||
if (adapterId != 0) {
|
||||
final Context c = context;
|
||||
@ -764,11 +764,12 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
|
||||
public void setOverScrollMode(int mode) {
|
||||
if (mode != OVER_SCROLL_NEVER) {
|
||||
if (mEdgeGlowTop == null) {
|
||||
final Resources res = getContext().getResources();
|
||||
Context context = getContext();
|
||||
final Resources res = context.getResources();
|
||||
final Drawable edge = res.getDrawable(R.drawable.overscroll_edge);
|
||||
final Drawable glow = res.getDrawable(R.drawable.overscroll_glow);
|
||||
mEdgeGlowTop = new EdgeGlow(edge, glow);
|
||||
mEdgeGlowBottom = new EdgeGlow(edge, glow);
|
||||
mEdgeGlowTop = new EdgeGlow(context, edge, glow);
|
||||
mEdgeGlowBottom = new EdgeGlow(context, edge, glow);
|
||||
}
|
||||
} else {
|
||||
mEdgeGlowTop = null;
|
||||
@ -1843,7 +1844,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
|
||||
* @param position The position to display
|
||||
* @param isScrap Array of at least 1 boolean, the first entry will become true if
|
||||
* the returned view was taken from the scrap heap, false if otherwise.
|
||||
*
|
||||
*
|
||||
* @return A view displaying the data associated with the specified position
|
||||
*/
|
||||
View obtainView(int position, boolean[] isScrap) {
|
||||
@ -2166,7 +2167,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
|
||||
treeObserver.addOnGlobalLayoutListener(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (mAdapter != null && mDataSetObserver == null) {
|
||||
mDataSetObserver = new AdapterDataSetObserver();
|
||||
mAdapter.registerDataSetObserver(mDataSetObserver);
|
||||
@ -2962,7 +2963,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
|
||||
mFlingRunnable = new FlingRunnable();
|
||||
}
|
||||
reportScrollStateChange(OnScrollListener.SCROLL_STATE_FLING);
|
||||
|
||||
|
||||
mFlingRunnable.start(-initialVelocity);
|
||||
} else {
|
||||
mTouchMode = TOUCH_MODE_REST;
|
||||
@ -3015,7 +3016,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
|
||||
mVelocityTracker.recycle();
|
||||
mVelocityTracker = null;
|
||||
}
|
||||
|
||||
|
||||
mActivePointerId = INVALID_POINTER;
|
||||
|
||||
if (PROFILE_SCROLLING) {
|
||||
@ -3064,7 +3065,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
|
||||
mVelocityTracker = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (mEdgeGlowTop != null) {
|
||||
mEdgeGlowTop.onRelease();
|
||||
mEdgeGlowBottom.onRelease();
|
||||
@ -3072,7 +3073,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
|
||||
mActivePointerId = INVALID_POINTER;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case MotionEvent.ACTION_POINTER_UP: {
|
||||
onSecondaryPointerUp(ev);
|
||||
final int x = mMotionX;
|
||||
@ -3170,11 +3171,11 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
|
||||
mMotionCorrection = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
final int x = (int) ev.getX();
|
||||
final int y = (int) ev.getY();
|
||||
mActivePointerId = ev.getPointerId(0);
|
||||
|
||||
|
||||
int motionPosition = findMotionRow(y);
|
||||
if (touchMode != TOUCH_MODE_FLING && motionPosition >= 0) {
|
||||
// User clicked on an actual view (and was not stopping a fling).
|
||||
@ -3213,7 +3214,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
|
||||
reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case MotionEvent.ACTION_POINTER_UP: {
|
||||
onSecondaryPointerUp(ev);
|
||||
break;
|
||||
@ -3222,7 +3223,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
private void onSecondaryPointerUp(MotionEvent ev) {
|
||||
final int pointerIndex = (ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) >>
|
||||
MotionEvent.ACTION_POINTER_INDEX_SHIFT;
|
||||
@ -3418,7 +3419,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
|
||||
default:
|
||||
endFling();
|
||||
return;
|
||||
|
||||
|
||||
case TOUCH_MODE_SCROLL:
|
||||
if (mScroller.isFinished()) {
|
||||
return;
|
||||
@ -3521,17 +3522,17 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
class PositionScroller implements Runnable {
|
||||
private static final int SCROLL_DURATION = 400;
|
||||
|
||||
|
||||
private static final int MOVE_DOWN_POS = 1;
|
||||
private static final int MOVE_UP_POS = 2;
|
||||
private static final int MOVE_DOWN_BOUND = 3;
|
||||
private static final int MOVE_UP_BOUND = 4;
|
||||
private static final int MOVE_OFFSET = 5;
|
||||
|
||||
|
||||
private int mMode;
|
||||
private int mTargetPos;
|
||||
private int mBoundPos;
|
||||
@ -3540,17 +3541,17 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
|
||||
private final int mExtraScroll;
|
||||
|
||||
private int mOffsetFromTop;
|
||||
|
||||
|
||||
PositionScroller() {
|
||||
mExtraScroll = ViewConfiguration.get(mContext).getScaledFadingEdgeLength();
|
||||
}
|
||||
|
||||
|
||||
void start(int position) {
|
||||
final int firstPos = mFirstPosition;
|
||||
final int lastPos = firstPos + getChildCount() - 1;
|
||||
|
||||
|
||||
int viewTravelCount;
|
||||
if (position <= firstPos) {
|
||||
if (position <= firstPos) {
|
||||
viewTravelCount = firstPos - position + 1;
|
||||
mMode = MOVE_UP_POS;
|
||||
} else if (position >= lastPos) {
|
||||
@ -3560,7 +3561,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
|
||||
// Already on screen, nothing to do
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (viewTravelCount > 0) {
|
||||
mScrollDuration = SCROLL_DURATION / viewTravelCount;
|
||||
} else {
|
||||
@ -3569,19 +3570,19 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
|
||||
mTargetPos = position;
|
||||
mBoundPos = INVALID_POSITION;
|
||||
mLastSeenPos = INVALID_POSITION;
|
||||
|
||||
|
||||
post(this);
|
||||
}
|
||||
|
||||
|
||||
void start(int position, int boundPosition) {
|
||||
if (boundPosition == INVALID_POSITION) {
|
||||
start(position);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
final int firstPos = mFirstPosition;
|
||||
final int lastPos = firstPos + getChildCount() - 1;
|
||||
|
||||
|
||||
int viewTravelCount;
|
||||
if (position <= firstPos) {
|
||||
final int boundPosFromLast = lastPos - boundPosition;
|
||||
@ -3589,7 +3590,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
|
||||
// Moving would shift our bound position off the screen. Abort.
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
final int posTravel = firstPos - position + 1;
|
||||
final int boundTravel = boundPosFromLast - 1;
|
||||
if (boundTravel < posTravel) {
|
||||
@ -3619,7 +3620,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
|
||||
// Already on screen, nothing to do
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (viewTravelCount > 0) {
|
||||
mScrollDuration = SCROLL_DURATION / viewTravelCount;
|
||||
} else {
|
||||
@ -3628,7 +3629,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
|
||||
mTargetPos = position;
|
||||
mBoundPos = boundPosition;
|
||||
mLastSeenPos = INVALID_POSITION;
|
||||
|
||||
|
||||
post(this);
|
||||
}
|
||||
|
||||
@ -3679,12 +3680,12 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
|
||||
|
||||
final int listHeight = getHeight();
|
||||
final int firstPos = mFirstPosition;
|
||||
|
||||
|
||||
switch (mMode) {
|
||||
case MOVE_DOWN_POS: {
|
||||
final int lastViewIndex = getChildCount() - 1;
|
||||
final int lastPos = firstPos + lastViewIndex;
|
||||
|
||||
|
||||
if (lastViewIndex < 0) {
|
||||
return;
|
||||
}
|
||||
@ -3710,11 +3711,11 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case MOVE_DOWN_BOUND: {
|
||||
final int nextViewIndex = 1;
|
||||
final int childCount = getChildCount();
|
||||
|
||||
|
||||
if (firstPos == mBoundPos || childCount <= nextViewIndex
|
||||
|| firstPos + childCount >= mItemCount) {
|
||||
return;
|
||||
@ -3739,13 +3740,13 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
|
||||
|
||||
post(this);
|
||||
} else {
|
||||
if (nextViewTop > extraScroll) {
|
||||
if (nextViewTop > extraScroll) {
|
||||
smoothScrollBy(nextViewTop - extraScroll, mScrollDuration);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case MOVE_UP_POS: {
|
||||
if (firstPos == mLastSeenPos) {
|
||||
// No new views, let things keep going.
|
||||
@ -3769,7 +3770,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case MOVE_UP_BOUND: {
|
||||
final int lastViewIndex = getChildCount() - 2;
|
||||
if (lastViewIndex < 0) {
|
||||
@ -3835,11 +3836,11 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The amount of friction applied to flings. The default value
|
||||
* is {@link ViewConfiguration#getScrollFriction}.
|
||||
*
|
||||
*
|
||||
* @return A scalar dimensionless value representing the coefficient of
|
||||
* friction.
|
||||
*/
|
||||
@ -3847,19 +3848,19 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
|
||||
if (mFlingRunnable == null) {
|
||||
mFlingRunnable = new FlingRunnable();
|
||||
}
|
||||
mFlingRunnable.mScroller.setFriction(friction);
|
||||
mFlingRunnable.mScroller.setFriction(friction);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a scale factor for the fling velocity. The initial scale
|
||||
* factor is 1.0.
|
||||
*
|
||||
*
|
||||
* @param scale The scale factor to multiply the velocity by.
|
||||
*/
|
||||
public void setVelocityScale(float scale) {
|
||||
mVelocityScale = scale;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Smoothly scroll to the specified adapter position. The view will
|
||||
* scroll such that the indicated position is displayed.
|
||||
@ -3913,7 +3914,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
|
||||
* Smoothly scroll to the specified adapter position. The view will
|
||||
* scroll such that the indicated position is displayed, but it will
|
||||
* stop early if scrolling further would scroll boundPosition out of
|
||||
* view.
|
||||
* view.
|
||||
* @param position Scroll to this adapter position.
|
||||
* @param boundPosition Do not scroll if it would move this adapter
|
||||
* position out of view.
|
||||
@ -3924,7 +3925,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
|
||||
}
|
||||
mPositionScroller.start(position, boundPosition);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Smoothly scroll by distance pixels over duration milliseconds.
|
||||
* @param distance Distance to scroll in pixels.
|
||||
@ -4145,7 +4146,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
|
||||
if (down) {
|
||||
mFirstPosition += count;
|
||||
}
|
||||
|
||||
|
||||
invalidate();
|
||||
|
||||
final int absIncrementalDeltaY = Math.abs(incrementalDeltaY);
|
||||
@ -4171,7 +4172,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
|
||||
|
||||
invokeOnItemScrollListener();
|
||||
awakenScrollBars();
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -5289,7 +5290,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
|
||||
mCurrentScrap = scrapViews[0];
|
||||
mScrapViews = scrapViews;
|
||||
}
|
||||
|
||||
|
||||
public void markChildrenDirty() {
|
||||
if (mViewTypeCount == 1) {
|
||||
final ArrayList<View> scrap = mCurrentScrap;
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
package android.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.view.animation.AnimationUtils;
|
||||
@ -44,7 +45,7 @@ public class EdgeGlow {
|
||||
private static final float HELD_GLOW_ALPHA = 0.5f;
|
||||
private static final float HELD_GLOW_SCALE_Y = 0.5f;
|
||||
|
||||
private static final float MAX_GLOW_HEIGHT = 3.f;
|
||||
private static final float MAX_GLOW_HEIGHT = 4.f;
|
||||
|
||||
private static final float PULL_GLOW_BEGIN = 1.f;
|
||||
private static final float PULL_EDGE_BEGIN = 0.6f;
|
||||
@ -58,6 +59,8 @@ public class EdgeGlow {
|
||||
private final Drawable mGlow;
|
||||
private int mWidth;
|
||||
private int mHeight;
|
||||
private final int MIN_WIDTH = 300;
|
||||
private final int mMinWidth;
|
||||
|
||||
private float mEdgeAlpha;
|
||||
private float mEdgeScaleY;
|
||||
@ -86,12 +89,12 @@ public class EdgeGlow {
|
||||
|
||||
// How much dragging should effect the height of the edge image.
|
||||
// Number determined by user testing.
|
||||
private static final int PULL_DISTANCE_EDGE_FACTOR = 5;
|
||||
private static final int PULL_DISTANCE_EDGE_FACTOR = 7;
|
||||
|
||||
// How much dragging should effect the height of the glow image.
|
||||
// Number determined by user testing.
|
||||
private static final int PULL_DISTANCE_GLOW_FACTOR = 5;
|
||||
private static final float PULL_DISTANCE_ALPHA_GLOW_FACTOR = 0.8f;
|
||||
private static final int PULL_DISTANCE_GLOW_FACTOR = 7;
|
||||
private static final float PULL_DISTANCE_ALPHA_GLOW_FACTOR = 1.1f;
|
||||
|
||||
private static final int VELOCITY_EDGE_FACTOR = 8;
|
||||
private static final int VELOCITY_GLOW_FACTOR = 16;
|
||||
@ -100,10 +103,11 @@ public class EdgeGlow {
|
||||
|
||||
private float mPullDistance;
|
||||
|
||||
public EdgeGlow(Drawable edge, Drawable glow) {
|
||||
public EdgeGlow(Context context, Drawable edge, Drawable glow) {
|
||||
mEdge = edge;
|
||||
mGlow = glow;
|
||||
|
||||
mMinWidth = (int) (context.getResources().getDisplayMetrics().density * MIN_WIDTH + 0.5f);
|
||||
mInterpolator = new DecelerateInterpolator();
|
||||
}
|
||||
|
||||
@ -251,17 +255,31 @@ public class EdgeGlow {
|
||||
|
||||
mGlow.setAlpha((int) (Math.max(0, Math.min(mGlowAlpha, 1)) * 255));
|
||||
|
||||
// Center the glow inside the width of the container.
|
||||
int glowLeft = (mWidth - glowWidth)/2;
|
||||
mGlow.setBounds(glowLeft, 0, mWidth - glowLeft, (int) Math.min(
|
||||
int glowBottom = (int) Math.min(
|
||||
glowHeight * mGlowScaleY * glowHeight/ glowWidth * 0.6f,
|
||||
glowHeight * MAX_GLOW_HEIGHT));
|
||||
glowHeight * MAX_GLOW_HEIGHT);
|
||||
if (mWidth < mMinWidth) {
|
||||
// Center the glow and clip it.
|
||||
int glowLeft = (mWidth - glowWidth)/2;
|
||||
mGlow.setBounds(glowLeft, 0, mWidth - glowLeft, glowBottom);
|
||||
} else {
|
||||
// Stretch the glow to fit.
|
||||
mGlow.setBounds(0, 0, mWidth, glowBottom);
|
||||
}
|
||||
|
||||
mGlow.draw(canvas);
|
||||
|
||||
mEdge.setAlpha((int) (Math.max(0, Math.min(mEdgeAlpha, 1)) * 255));
|
||||
|
||||
int edgeLeft = (mWidth - edgeWidth)/2;
|
||||
mEdge.setBounds(edgeLeft, 0, mWidth - edgeLeft, (int) (edgeHeight * mEdgeScaleY));
|
||||
int edgeBottom = (int) (edgeHeight * mEdgeScaleY);
|
||||
if (mWidth < mMinWidth) {
|
||||
// Center the edge and clip it.
|
||||
int edgeLeft = (mWidth - edgeWidth)/2;
|
||||
mEdge.setBounds(edgeLeft, 0, mWidth - edgeLeft, edgeBottom);
|
||||
} else {
|
||||
// Stretch the edge to fit.
|
||||
mEdge.setBounds(0, 0, mWidth, edgeBottom);
|
||||
}
|
||||
mEdge.draw(canvas);
|
||||
|
||||
return mState != STATE_IDLE;
|
||||
|
@ -58,8 +58,8 @@ import java.util.List;
|
||||
* within a larger container.
|
||||
*
|
||||
* <p>HorizontalScrollView only supports horizontal scrolling.
|
||||
*
|
||||
* @attr ref android.R.styleable#HorizontalScrollView_fillViewport
|
||||
*
|
||||
* @attr ref android.R.styleable#HorizontalScrollView_fillViewport
|
||||
*/
|
||||
public class HorizontalScrollView extends FrameLayout {
|
||||
private static final int ANIMATED_SCROLL_GAP = ScrollView.ANIMATED_SCROLL_GAP;
|
||||
@ -125,7 +125,7 @@ public class HorizontalScrollView extends FrameLayout {
|
||||
private int mTouchSlop;
|
||||
private int mMinimumVelocity;
|
||||
private int mMaximumVelocity;
|
||||
|
||||
|
||||
private int mOverscrollDistance;
|
||||
private int mOverflingDistance;
|
||||
|
||||
@ -134,13 +134,13 @@ public class HorizontalScrollView extends FrameLayout {
|
||||
* drags/flings if multiple pointers are used.
|
||||
*/
|
||||
private int mActivePointerId = INVALID_POINTER;
|
||||
|
||||
|
||||
/**
|
||||
* Sentinel value for no current active pointer.
|
||||
* Used by {@link #mActivePointerId}.
|
||||
*/
|
||||
private static final int INVALID_POINTER = -1;
|
||||
|
||||
|
||||
public HorizontalScrollView(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
@ -279,7 +279,7 @@ public class HorizontalScrollView extends FrameLayout {
|
||||
*
|
||||
* @param fillViewport True to stretch the content's width to the viewport's
|
||||
* boundaries, false otherwise.
|
||||
*
|
||||
*
|
||||
* @attr ref android.R.styleable#HorizontalScrollView_fillViewport
|
||||
*/
|
||||
public void setFillViewport(boolean fillViewport) {
|
||||
@ -322,13 +322,13 @@ public class HorizontalScrollView extends FrameLayout {
|
||||
int width = getMeasuredWidth();
|
||||
if (child.getMeasuredWidth() < width) {
|
||||
final FrameLayout.LayoutParams lp = (LayoutParams) child.getLayoutParams();
|
||||
|
||||
|
||||
int childHeightMeasureSpec = getChildMeasureSpec(heightMeasureSpec, mPaddingTop
|
||||
+ mPaddingBottom, lp.height);
|
||||
width -= mPaddingLeft;
|
||||
width -= mPaddingRight;
|
||||
int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY);
|
||||
|
||||
|
||||
child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
|
||||
}
|
||||
}
|
||||
@ -400,7 +400,7 @@ public class HorizontalScrollView extends FrameLayout {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean onInterceptTouchEvent(MotionEvent ev) {
|
||||
/*
|
||||
@ -453,7 +453,7 @@ public class HorizontalScrollView extends FrameLayout {
|
||||
mIsBeingDragged = false;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Remember location of down touch.
|
||||
* ACTION_DOWN always refers to pointer index 0.
|
||||
@ -581,7 +581,7 @@ public class HorizontalScrollView extends FrameLayout {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
mActivePointerId = INVALID_POINTER;
|
||||
mIsBeingDragged = false;
|
||||
|
||||
@ -618,7 +618,7 @@ public class HorizontalScrollView extends FrameLayout {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
private void onSecondaryPointerUp(MotionEvent ev) {
|
||||
final int pointerIndex = (ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) >>
|
||||
MotionEvent.ACTION_POINTER_INDEX_SHIFT;
|
||||
@ -635,7 +635,7 @@ public class HorizontalScrollView extends FrameLayout {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onOverScrolled(int scrollX, int scrollY,
|
||||
boolean clampedX, boolean clampedY) {
|
||||
@ -917,7 +917,7 @@ public class HorizontalScrollView extends FrameLayout {
|
||||
if (direction == View.FOCUS_LEFT && getScrollX() < scrollDelta) {
|
||||
scrollDelta = getScrollX();
|
||||
} else if (direction == View.FOCUS_RIGHT && getChildCount() > 0) {
|
||||
|
||||
|
||||
int daRight = getChildAt(0).getRight();
|
||||
|
||||
int screenRight = getScrollX() + getWidth();
|
||||
@ -1033,7 +1033,7 @@ public class HorizontalScrollView extends FrameLayout {
|
||||
if (count == 0) {
|
||||
return contentWidth;
|
||||
}
|
||||
|
||||
|
||||
int scrollRange = getChildAt(0).getRight();
|
||||
final int scrollX = mScrollX;
|
||||
final int overscrollRight = Math.max(0, scrollRange - contentWidth);
|
||||
@ -1045,7 +1045,7 @@ public class HorizontalScrollView extends FrameLayout {
|
||||
|
||||
return scrollRange;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected int computeHorizontalScrollOffset() {
|
||||
return Math.max(0, super.computeHorizontalScrollOffset());
|
||||
@ -1352,25 +1352,25 @@ public class HorizontalScrollView extends FrameLayout {
|
||||
if (getChildCount() > 0) {
|
||||
int width = getWidth() - mPaddingRight - mPaddingLeft;
|
||||
int right = getChildAt(0).getWidth();
|
||||
|
||||
mScroller.fling(mScrollX, mScrollY, velocityX, 0, 0,
|
||||
|
||||
mScroller.fling(mScrollX, mScrollY, velocityX, 0, 0,
|
||||
Math.max(0, right - width), 0, 0, width/2, 0);
|
||||
|
||||
|
||||
final boolean movingRight = velocityX > 0;
|
||||
|
||||
|
||||
View newFocused = findFocusableViewInMyBounds(movingRight,
|
||||
mScroller.getFinalX(), findFocus());
|
||||
|
||||
|
||||
if (newFocused == null) {
|
||||
newFocused = this;
|
||||
}
|
||||
|
||||
|
||||
if (newFocused != findFocus()
|
||||
&& newFocused.requestFocus(movingRight ? View.FOCUS_RIGHT : View.FOCUS_LEFT)) {
|
||||
mScrollViewMovedFocus = true;
|
||||
mScrollViewMovedFocus = false;
|
||||
}
|
||||
|
||||
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
@ -1396,11 +1396,12 @@ public class HorizontalScrollView extends FrameLayout {
|
||||
public void setOverScrollMode(int mode) {
|
||||
if (mode != OVER_SCROLL_NEVER) {
|
||||
if (mEdgeGlowLeft == null) {
|
||||
final Resources res = getContext().getResources();
|
||||
Context context = getContext();
|
||||
final Resources res = context.getResources();
|
||||
final Drawable edge = res.getDrawable(R.drawable.overscroll_edge);
|
||||
final Drawable glow = res.getDrawable(R.drawable.overscroll_glow);
|
||||
mEdgeGlowLeft = new EdgeGlow(edge, glow);
|
||||
mEdgeGlowRight = new EdgeGlow(edge, glow);
|
||||
mEdgeGlowLeft = new EdgeGlow(context, edge, glow);
|
||||
mEdgeGlowRight = new EdgeGlow(context, edge, glow);
|
||||
}
|
||||
} else {
|
||||
mEdgeGlowLeft = null;
|
||||
|
@ -51,7 +51,7 @@ import java.util.List;
|
||||
* takes care of its own scrolling, so does not require a ScrollView, but
|
||||
* using the two together is possible to achieve the effect of a text view
|
||||
* within a larger container.
|
||||
*
|
||||
*
|
||||
* <p>ScrollView only supports vertical scrolling.
|
||||
*
|
||||
* @attr ref android.R.styleable#ScrollView_fillViewport
|
||||
@ -120,7 +120,7 @@ public class ScrollView extends FrameLayout {
|
||||
private int mTouchSlop;
|
||||
private int mMinimumVelocity;
|
||||
private int mMaximumVelocity;
|
||||
|
||||
|
||||
private int mOverscrollDistance;
|
||||
private int mOverflingDistance;
|
||||
|
||||
@ -269,7 +269,7 @@ public class ScrollView extends FrameLayout {
|
||||
* Indicates whether this ScrollView's content is stretched to fill the viewport.
|
||||
*
|
||||
* @return True if the content fills the viewport, false otherwise.
|
||||
*
|
||||
*
|
||||
* @attr ref android.R.styleable#ScrollView_fillViewport
|
||||
*/
|
||||
public boolean isFillViewport() {
|
||||
@ -282,7 +282,7 @@ public class ScrollView extends FrameLayout {
|
||||
*
|
||||
* @param fillViewport True to stretch the content's height to the viewport's
|
||||
* boundaries, false otherwise.
|
||||
*
|
||||
*
|
||||
* @attr ref android.R.styleable#ScrollView_fillViewport
|
||||
*/
|
||||
public void setFillViewport(boolean fillViewport) {
|
||||
@ -325,14 +325,14 @@ public class ScrollView extends FrameLayout {
|
||||
int height = getMeasuredHeight();
|
||||
if (child.getMeasuredHeight() < height) {
|
||||
final FrameLayout.LayoutParams lp = (LayoutParams) child.getLayoutParams();
|
||||
|
||||
|
||||
int childWidthMeasureSpec = getChildMeasureSpec(widthMeasureSpec, mPaddingLeft
|
||||
+ mPaddingRight, lp.width);
|
||||
height -= mPaddingTop;
|
||||
height -= mPaddingBottom;
|
||||
int childHeightMeasureSpec =
|
||||
MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
|
||||
|
||||
|
||||
child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
|
||||
}
|
||||
}
|
||||
@ -521,7 +521,7 @@ public class ScrollView extends FrameLayout {
|
||||
case MotionEvent.ACTION_DOWN: {
|
||||
final float y = ev.getY();
|
||||
mIsBeingDragged = true;
|
||||
|
||||
|
||||
/*
|
||||
* If being flinged and user touches, stop the fling. isFinished
|
||||
* will be false if being flinged.
|
||||
@ -579,7 +579,7 @@ public class ScrollView extends FrameLayout {
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MotionEvent.ACTION_UP:
|
||||
case MotionEvent.ACTION_UP:
|
||||
if (mIsBeingDragged) {
|
||||
final VelocityTracker velocityTracker = mVelocityTracker;
|
||||
velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
|
||||
@ -615,7 +615,7 @@ public class ScrollView extends FrameLayout {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
private void onSecondaryPointerUp(MotionEvent ev) {
|
||||
final int pointerIndex = (ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) >>
|
||||
MotionEvent.ACTION_POINTER_INDEX_SHIFT;
|
||||
@ -632,7 +632,7 @@ public class ScrollView extends FrameLayout {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onOverScrolled(int scrollX, int scrollY,
|
||||
boolean clampedX, boolean clampedY) {
|
||||
@ -919,9 +919,9 @@ public class ScrollView extends FrameLayout {
|
||||
} else if (direction == View.FOCUS_DOWN) {
|
||||
if (getChildCount() > 0) {
|
||||
int daBottom = getChildAt(0).getBottom();
|
||||
|
||||
|
||||
int screenBottom = getScrollY() + getHeight();
|
||||
|
||||
|
||||
if (daBottom - screenBottom < maxJump) {
|
||||
scrollDelta = daBottom - screenBottom;
|
||||
}
|
||||
@ -1038,7 +1038,7 @@ public class ScrollView extends FrameLayout {
|
||||
if (count == 0) {
|
||||
return contentHeight;
|
||||
}
|
||||
|
||||
|
||||
int scrollRange = getChildAt(0).getBottom();
|
||||
final int scrollY = mScrollY;
|
||||
final int overscrollBottom = Math.max(0, scrollRange - contentHeight);
|
||||
@ -1289,7 +1289,7 @@ public class ScrollView extends FrameLayout {
|
||||
}
|
||||
|
||||
return nextFocus.requestFocus(direction, previouslyFocusedRect);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean requestChildRectangleOnScreen(View child, Rect rectangle,
|
||||
@ -1325,7 +1325,7 @@ public class ScrollView extends FrameLayout {
|
||||
protected void onLayout(boolean changed, int l, int t, int r, int b) {
|
||||
super.onLayout(changed, l, t, r, b);
|
||||
mIsLayoutDirty = false;
|
||||
// Give a child focus if it needs it
|
||||
// Give a child focus if it needs it
|
||||
if (mChildToScrollTo != null && isViewDescendantOf(mChildToScrollTo, this)) {
|
||||
scrollToChild(mChildToScrollTo);
|
||||
}
|
||||
@ -1352,7 +1352,7 @@ public class ScrollView extends FrameLayout {
|
||||
int scrollDelta = computeScrollDeltaToGetChildRectOnScreen(mTempRect);
|
||||
doScrollY(scrollDelta);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if child is an descendant of parent, (or equal to the parent).
|
||||
@ -1364,7 +1364,7 @@ public class ScrollView extends FrameLayout {
|
||||
|
||||
final ViewParent theParent = child.getParent();
|
||||
return (theParent instanceof ViewGroup) && isViewDescendantOf((View) theParent, parent);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fling the scroll view
|
||||
@ -1377,18 +1377,18 @@ public class ScrollView extends FrameLayout {
|
||||
if (getChildCount() > 0) {
|
||||
int height = getHeight() - mPaddingBottom - mPaddingTop;
|
||||
int bottom = getChildAt(0).getHeight();
|
||||
|
||||
mScroller.fling(mScrollX, mScrollY, 0, velocityY, 0, 0, 0,
|
||||
|
||||
mScroller.fling(mScrollX, mScrollY, 0, velocityY, 0, 0, 0,
|
||||
Math.max(0, bottom - height), 0, height/2);
|
||||
|
||||
|
||||
final boolean movingDown = velocityY > 0;
|
||||
|
||||
|
||||
View newFocused =
|
||||
findFocusableViewInMyBounds(movingDown, mScroller.getFinalY(), findFocus());
|
||||
if (newFocused == null) {
|
||||
newFocused = this;
|
||||
}
|
||||
|
||||
|
||||
if (newFocused != findFocus()
|
||||
&& newFocused.requestFocus(movingDown ? View.FOCUS_DOWN : View.FOCUS_UP)) {
|
||||
mScrollViewMovedFocus = true;
|
||||
@ -1444,11 +1444,12 @@ public class ScrollView extends FrameLayout {
|
||||
public void setOverScrollMode(int mode) {
|
||||
if (mode != OVER_SCROLL_NEVER) {
|
||||
if (mEdgeGlowTop == null) {
|
||||
final Resources res = getContext().getResources();
|
||||
Context context = getContext();
|
||||
final Resources res = context.getResources();
|
||||
final Drawable edge = res.getDrawable(R.drawable.overscroll_edge);
|
||||
final Drawable glow = res.getDrawable(R.drawable.overscroll_glow);
|
||||
mEdgeGlowTop = new EdgeGlow(edge, glow);
|
||||
mEdgeGlowBottom = new EdgeGlow(edge, glow);
|
||||
mEdgeGlowTop = new EdgeGlow(context, edge, glow);
|
||||
mEdgeGlowBottom = new EdgeGlow(context, edge, glow);
|
||||
}
|
||||
} else {
|
||||
mEdgeGlowTop = null;
|
||||
|
Reference in New Issue
Block a user