Added OverScroller and overscroll effects for ScrollView and HorizontalScrollView.
This commit is contained in:
@@ -63,7 +63,7 @@ public class HorizontalScrollView extends FrameLayout {
|
||||
private long mLastScroll;
|
||||
|
||||
private final Rect mTempRect = new Rect();
|
||||
private Scroller mScroller;
|
||||
private OverScroller mScroller;
|
||||
|
||||
/**
|
||||
* Flag to indicate that we are moving focus ourselves. This is so the
|
||||
@@ -177,7 +177,7 @@ public class HorizontalScrollView extends FrameLayout {
|
||||
|
||||
|
||||
private void initScrollView() {
|
||||
mScroller = new Scroller(getContext());
|
||||
mScroller = new OverScroller(getContext());
|
||||
setFocusable(true);
|
||||
setDescendantFocusability(FOCUS_AFTER_DESCENDANTS);
|
||||
setWillNotDraw(false);
|
||||
@@ -380,11 +380,6 @@ public class HorizontalScrollView extends FrameLayout {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!canScroll()) {
|
||||
mIsBeingDragged = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
final float x = ev.getX();
|
||||
|
||||
switch (action) {
|
||||
@@ -440,10 +435,6 @@ public class HorizontalScrollView extends FrameLayout {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!canScroll()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mVelocityTracker == null) {
|
||||
mVelocityTracker = VelocityTracker.obtain();
|
||||
}
|
||||
@@ -470,25 +461,23 @@ public class HorizontalScrollView extends FrameLayout {
|
||||
final int deltaX = (int) (mLastMotionX - x);
|
||||
mLastMotionX = x;
|
||||
|
||||
if (deltaX < 0) {
|
||||
if (mScrollX > 0) {
|
||||
scrollBy(deltaX, 0);
|
||||
}
|
||||
} else if (deltaX > 0) {
|
||||
final int rightEdge = getWidth() - mPaddingRight;
|
||||
final int availableToScroll = getChildAt(0).getRight() - mScrollX - rightEdge;
|
||||
if (availableToScroll > 0) {
|
||||
scrollBy(Math.min(availableToScroll, deltaX), 0);
|
||||
}
|
||||
}
|
||||
super.scrollTo(mScrollX + deltaX, mScrollY);
|
||||
break;
|
||||
case MotionEvent.ACTION_UP:
|
||||
final VelocityTracker velocityTracker = mVelocityTracker;
|
||||
velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
|
||||
int initialVelocity = (int) velocityTracker.getXVelocity();
|
||||
|
||||
if ((Math.abs(initialVelocity) > mMinimumVelocity) && getChildCount() > 0) {
|
||||
fling(-initialVelocity);
|
||||
if (getChildCount() > 0) {
|
||||
if ((Math.abs(initialVelocity) > mMinimumVelocity)) {
|
||||
fling(-initialVelocity);
|
||||
} else {
|
||||
final int right = Math.max(0, getChildAt(0).getHeight() -
|
||||
(getHeight() - mPaddingRight - mPaddingLeft));
|
||||
if (mScroller.springback(mScrollX, mScrollY, 0, 0, right, 0)) {
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mVelocityTracker != null) {
|
||||
@@ -913,14 +902,10 @@ public class HorizontalScrollView extends FrameLayout {
|
||||
int oldY = mScrollY;
|
||||
int x = mScroller.getCurrX();
|
||||
int y = mScroller.getCurrY();
|
||||
if (getChildCount() > 0) {
|
||||
View child = getChildAt(0);
|
||||
mScrollX = clamp(x, getWidth() - mPaddingRight - mPaddingLeft, child.getWidth());
|
||||
mScrollY = clamp(y, getHeight() - mPaddingBottom - mPaddingTop, child.getHeight());
|
||||
} else {
|
||||
mScrollX = x;
|
||||
mScrollY = y;
|
||||
}
|
||||
|
||||
mScrollX = x;
|
||||
mScrollY = y;
|
||||
|
||||
if (oldX != mScrollX || oldY != mScrollY) {
|
||||
onScrollChanged(mScrollX, mScrollY, oldX, oldY);
|
||||
}
|
||||
@@ -1156,7 +1141,8 @@ public class HorizontalScrollView extends FrameLayout {
|
||||
int width = getWidth() - mPaddingRight - mPaddingLeft;
|
||||
int right = getChildAt(0).getWidth();
|
||||
|
||||
mScroller.fling(mScrollX, mScrollY, velocityX, 0, 0, right - width, 0, 0);
|
||||
mScroller.fling(mScrollX, mScrollY, velocityX, 0, 0,
|
||||
Math.max(0, right - width), 0, 0, width/2, 0);
|
||||
|
||||
final boolean movingRight = velocityX > 0;
|
||||
|
||||
|
||||
354
core/java/android/widget/OverScroller.java
Normal file
354
core/java/android/widget/OverScroller.java
Normal file
@@ -0,0 +1,354 @@
|
||||
/*
|
||||
* Copyright (C) 2006 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.animation.AccelerateDecelerateInterpolator;
|
||||
import android.view.animation.DecelerateInterpolator;
|
||||
|
||||
/**
|
||||
* This class encapsulates scrolling with the ability to overshoot the bounds
|
||||
* of a scrolling operation. This class attempts to be a drop-in replacement
|
||||
* for {@link android.widget.Scroller} in most cases.
|
||||
*
|
||||
* @hide Pending API approval
|
||||
*/
|
||||
public class OverScroller {
|
||||
private static final int SPRINGBACK_DURATION = 150;
|
||||
private static final int OVERFLING_DURATION = 150;
|
||||
|
||||
private static final int MODE_DEFAULT = 0;
|
||||
private static final int MODE_OVERFLING = 1;
|
||||
private static final int MODE_SPRINGBACK = 2;
|
||||
|
||||
private Scroller mDefaultScroller;
|
||||
private Scroller mDecelScroller;
|
||||
private Scroller mAccelDecelScroller;
|
||||
private Scroller mCurrScroller;
|
||||
|
||||
private int mScrollMode = MODE_DEFAULT;
|
||||
|
||||
private int mMinimumX;
|
||||
private int mMinimumY;
|
||||
private int mMaximumX;
|
||||
private int mMaximumY;
|
||||
|
||||
public OverScroller(Context context) {
|
||||
mDefaultScroller = new Scroller(context);
|
||||
mDecelScroller = new Scroller(context, new DecelerateInterpolator(3.f));
|
||||
mAccelDecelScroller = new Scroller(context, new AccelerateDecelerateInterpolator());
|
||||
mCurrScroller = mDefaultScroller;
|
||||
}
|
||||
|
||||
/**
|
||||
* Call this when you want to know the new location. If it returns true,
|
||||
* the animation is not yet finished. loc will be altered to provide the
|
||||
* new location.
|
||||
*/
|
||||
public boolean computeScrollOffset() {
|
||||
boolean inProgress = mCurrScroller.computeScrollOffset();
|
||||
|
||||
switch (mScrollMode) {
|
||||
case MODE_OVERFLING:
|
||||
if (!inProgress) {
|
||||
// Overfling ended
|
||||
if (springback(mCurrScroller.getCurrX(), mCurrScroller.getCurrY(),
|
||||
mMinimumX, mMaximumX, mMinimumY, mMaximumY, mAccelDecelScroller)) {
|
||||
return mCurrScroller.computeScrollOffset();
|
||||
} else {
|
||||
mCurrScroller = mDefaultScroller;
|
||||
mScrollMode = MODE_DEFAULT;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case MODE_SPRINGBACK:
|
||||
if (!inProgress) {
|
||||
mCurrScroller = mDefaultScroller;
|
||||
mScrollMode = MODE_DEFAULT;
|
||||
}
|
||||
break;
|
||||
|
||||
case MODE_DEFAULT:
|
||||
// Fling/autoscroll - did we go off the edge?
|
||||
if (inProgress) {
|
||||
Scroller scroller = mCurrScroller;
|
||||
final int x = scroller.getCurrX();
|
||||
final int y = scroller.getCurrY();
|
||||
final int minX = mMinimumX;
|
||||
final int maxX = mMaximumX;
|
||||
final int minY = mMinimumY;
|
||||
final int maxY = mMaximumY;
|
||||
if (x < minX || x > maxX || y < minY || y > maxY) {
|
||||
final int startx = scroller.getStartX();
|
||||
final int starty = scroller.getStartY();
|
||||
final int time = scroller.timePassed();
|
||||
final float timeSecs = time / 1000.f;
|
||||
final float xvel = ((x - startx) / timeSecs);
|
||||
final float yvel = ((y - starty) / timeSecs);
|
||||
|
||||
if ((x < minX && xvel > 0) || (y < minY && yvel > 0) ||
|
||||
(x > maxX && xvel < 0) || (y > maxY && yvel < 0)) {
|
||||
// If our velocity would take us back into valid areas,
|
||||
// try to springback rather than overfling.
|
||||
if (springback(x, y, minX, maxX, minY, maxY)) {
|
||||
return mCurrScroller.computeScrollOffset();
|
||||
}
|
||||
} else {
|
||||
overfling(x, y, xvel, yvel);
|
||||
return mCurrScroller.computeScrollOffset();
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return inProgress;
|
||||
}
|
||||
|
||||
private void overfling(int startx, int starty, float xvel, float yvel) {
|
||||
Scroller scroller = mDecelScroller;
|
||||
final float durationSecs = (OVERFLING_DURATION / 1000.f);
|
||||
int dx = (int)(xvel * durationSecs) / 8;
|
||||
int dy = (int)(yvel * durationSecs) / 8;
|
||||
scroller.startScroll(startx, starty, dx, dy, OVERFLING_DURATION);
|
||||
mCurrScroller.abortAnimation();
|
||||
mCurrScroller = scroller;
|
||||
mScrollMode = MODE_OVERFLING;
|
||||
}
|
||||
|
||||
/**
|
||||
* Call this when you want to 'spring back' into a valid coordinate range.
|
||||
*
|
||||
* @param startX Starting X coordinate
|
||||
* @param startY Starting Y coordinate
|
||||
* @param minX Minimum valid X value
|
||||
* @param maxX Maximum valid X value
|
||||
* @param minY Minimum valid Y value
|
||||
* @param maxY Minimum valid Y value
|
||||
* @return true if a springback was initiated, false if startX/startY was
|
||||
* already within the valid range.
|
||||
*/
|
||||
public boolean springback(int startX, int startY, int minX, int maxX,
|
||||
int minY, int maxY) {
|
||||
return springback(startX, startY, minX, maxX, minY, maxY, mDecelScroller);
|
||||
}
|
||||
|
||||
private boolean springback(int startX, int startY, int minX, int maxX,
|
||||
int minY, int maxY, Scroller scroller) {
|
||||
int xoff = 0;
|
||||
int yoff = 0;
|
||||
if (startX < minX) {
|
||||
xoff = minX - startX;
|
||||
} else if (startX > maxX) {
|
||||
xoff = maxX - startX;
|
||||
}
|
||||
if (startY < minY) {
|
||||
yoff = minY - startY;
|
||||
} else if (startY > maxY) {
|
||||
yoff = maxY - startY;
|
||||
}
|
||||
|
||||
if (xoff != 0 || yoff != 0) {
|
||||
scroller.startScroll(startX, startY, xoff, yoff, SPRINGBACK_DURATION);
|
||||
mCurrScroller.abortAnimation();
|
||||
mCurrScroller = scroller;
|
||||
mScrollMode = MODE_SPRINGBACK;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Returns whether the scroller has finished scrolling.
|
||||
*
|
||||
* @return True if the scroller has finished scrolling, false otherwise.
|
||||
*/
|
||||
public final boolean isFinished() {
|
||||
return mCurrScroller.isFinished();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current X offset in the scroll.
|
||||
*
|
||||
* @return The new X offset as an absolute distance from the origin.
|
||||
*/
|
||||
public final int getCurrX() {
|
||||
return mCurrScroller.getCurrX();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current Y offset in the scroll.
|
||||
*
|
||||
* @return The new Y offset as an absolute distance from the origin.
|
||||
*/
|
||||
public final int getCurrY() {
|
||||
return mCurrScroller.getCurrY();
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops the animation, resets any springback/overfling and completes
|
||||
* any standard flings/scrolls in progress.
|
||||
*/
|
||||
public void abortAnimation() {
|
||||
mCurrScroller.abortAnimation();
|
||||
mCurrScroller = mDefaultScroller;
|
||||
mScrollMode = MODE_DEFAULT;
|
||||
mCurrScroller.abortAnimation();
|
||||
}
|
||||
|
||||
/**
|
||||
* Start scrolling by providing a starting point and the distance to travel.
|
||||
* The scroll will use the default value of 250 milliseconds for the
|
||||
* duration.
|
||||
*
|
||||
* @param startX Starting horizontal scroll offset in pixels. Positive
|
||||
* numbers will scroll the content to the left.
|
||||
* @param startY Starting vertical scroll offset in pixels. Positive numbers
|
||||
* will scroll the content up.
|
||||
* @param dx Horizontal distance to travel. Positive numbers will scroll the
|
||||
* content to the left.
|
||||
* @param dy Vertical distance to travel. Positive numbers will scroll the
|
||||
* content up.
|
||||
*/
|
||||
public void startScroll(int startX, int startY, int dx, int dy) {
|
||||
mCurrScroller.abortAnimation();
|
||||
mCurrScroller = mDefaultScroller;
|
||||
mScrollMode = MODE_DEFAULT;
|
||||
mMinimumX = Math.min(startX, startX + dx);
|
||||
mMinimumY = Math.min(startY, startY + dy);
|
||||
mMaximumX = Math.max(startX, startX + dx);
|
||||
mMaximumY = Math.max(startY, startY + dy);
|
||||
mCurrScroller.startScroll(startX, startY, dx, dy);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start scrolling by providing a starting point and the distance to travel.
|
||||
*
|
||||
* @param startX Starting horizontal scroll offset in pixels. Positive
|
||||
* numbers will scroll the content to the left.
|
||||
* @param startY Starting vertical scroll offset in pixels. Positive numbers
|
||||
* will scroll the content up.
|
||||
* @param dx Horizontal distance to travel. Positive numbers will scroll the
|
||||
* content to the left.
|
||||
* @param dy Vertical distance to travel. Positive numbers will scroll the
|
||||
* content up.
|
||||
* @param duration Duration of the scroll in milliseconds.
|
||||
*/
|
||||
public void startScroll(int startX, int startY, int dx, int dy, int duration) {
|
||||
mCurrScroller.abortAnimation();
|
||||
mCurrScroller = mDefaultScroller;
|
||||
mScrollMode = MODE_DEFAULT;
|
||||
mMinimumX = Math.min(startX, startX + dx);
|
||||
mMinimumY = Math.min(startY, startY + dy);
|
||||
mMaximumX = Math.max(startX, startX + dx);
|
||||
mMaximumY = Math.max(startY, startY + dy);
|
||||
mCurrScroller.startScroll(startX, startY, dx, dy, duration);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the duration of the active scroll in progress; standard, fling,
|
||||
* springback, or overfling. Does not account for any overflings or springback
|
||||
* that may result.
|
||||
*/
|
||||
public int getDuration() {
|
||||
return mCurrScroller.getDuration();
|
||||
}
|
||||
|
||||
/**
|
||||
* Start scrolling based on a fling gesture. The distance travelled will
|
||||
* depend on the initial velocity of the fling.
|
||||
*
|
||||
* @param startX Starting point of the scroll (X)
|
||||
* @param startY Starting point of the scroll (Y)
|
||||
* @param velocityX Initial velocity of the fling (X) measured in pixels per
|
||||
* second.
|
||||
* @param velocityY Initial velocity of the fling (Y) measured in pixels per
|
||||
* second
|
||||
* @param minX Minimum X value. The scroller will not scroll past this
|
||||
* point.
|
||||
* @param maxX Maximum X value. The scroller will not scroll past this
|
||||
* point.
|
||||
* @param minY Minimum Y value. The scroller will not scroll past this
|
||||
* point.
|
||||
* @param maxY Maximum Y value. The scroller will not scroll past this
|
||||
* point.
|
||||
*/
|
||||
public void fling(int startX, int startY, int velocityX, int velocityY,
|
||||
int minX, int maxX, int minY, int maxY) {
|
||||
this.fling(startX, startY, velocityX, velocityY, minX, maxX, minY, maxY, 0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start scrolling based on a fling gesture. The distance travelled will
|
||||
* depend on the initial velocity of the fling.
|
||||
*
|
||||
* @param startX Starting point of the scroll (X)
|
||||
* @param startY Starting point of the scroll (Y)
|
||||
* @param velocityX Initial velocity of the fling (X) measured in pixels per
|
||||
* second.
|
||||
* @param velocityY Initial velocity of the fling (Y) measured in pixels per
|
||||
* second
|
||||
* @param minX Minimum X value. The scroller will not scroll past this
|
||||
* point unless overX > 0. If overfling is allowed, it will use minX
|
||||
* as a springback boundary.
|
||||
* @param maxX Maximum X value. The scroller will not scroll past this
|
||||
* point unless overX > 0. If overfling is allowed, it will use maxX
|
||||
* as a springback boundary.
|
||||
* @param minY Minimum Y value. The scroller will not scroll past this
|
||||
* point unless overY > 0. If overfling is allowed, it will use minY
|
||||
* as a springback boundary.
|
||||
* @param maxY Maximum Y value. The scroller will not scroll past this
|
||||
* point unless overY > 0. If overfling is allowed, it will use maxY
|
||||
* as a springback boundary.
|
||||
* @param overX Overfling range. If > 0, horizontal overfling in either
|
||||
* direction will be possible.
|
||||
* @param overY Overfling range. If > 0, vertical overfling in either
|
||||
* direction will be possible.
|
||||
*/
|
||||
public void fling(int startX, int startY, int velocityX, int velocityY,
|
||||
int minX, int maxX, int minY, int maxY, int overX, int overY) {
|
||||
mCurrScroller = mDefaultScroller;
|
||||
mScrollMode = MODE_DEFAULT;
|
||||
mMinimumX = minX;
|
||||
mMaximumX = maxX;
|
||||
mMinimumY = minY;
|
||||
mMaximumY = maxY;
|
||||
mCurrScroller.fling(startX, startY, velocityX, velocityY,
|
||||
minX - overX, maxX + overX, minY - overY, maxY + overY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns where the scroll will end. Valid only for "fling" scrolls.
|
||||
*
|
||||
* @return The final X offset as an absolute distance from the origin.
|
||||
*/
|
||||
public int getFinalX() {
|
||||
return mCurrScroller.getFinalX();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns where the scroll will end. Valid only for "fling" scrolls.
|
||||
*
|
||||
* @return The final Y offset as an absolute distance from the origin.
|
||||
*/
|
||||
public int getFinalY() {
|
||||
return mCurrScroller.getFinalY();
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package android.widget;
|
||||
|
||||
import com.android.internal.R;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Rect;
|
||||
@@ -30,8 +32,6 @@ import android.view.ViewGroup;
|
||||
import android.view.ViewParent;
|
||||
import android.view.animation.AnimationUtils;
|
||||
|
||||
import com.android.internal.R;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -59,7 +59,7 @@ public class ScrollView extends FrameLayout {
|
||||
private long mLastScroll;
|
||||
|
||||
private final Rect mTempRect = new Rect();
|
||||
private Scroller mScroller;
|
||||
private OverScroller mScroller;
|
||||
|
||||
/**
|
||||
* Flag to indicate that we are moving focus ourselves. This is so the
|
||||
@@ -173,7 +173,7 @@ public class ScrollView extends FrameLayout {
|
||||
|
||||
|
||||
private void initScrollView() {
|
||||
mScroller = new Scroller(getContext());
|
||||
mScroller = new OverScroller(getContext());
|
||||
setFocusable(true);
|
||||
setDescendantFocusability(FOCUS_AFTER_DESCENDANTS);
|
||||
setWillNotDraw(false);
|
||||
@@ -378,11 +378,6 @@ public class ScrollView extends FrameLayout {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!canScroll()) {
|
||||
mIsBeingDragged = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
final float y = ev.getY();
|
||||
|
||||
switch (action) {
|
||||
@@ -437,10 +432,6 @@ public class ScrollView extends FrameLayout {
|
||||
// descendants.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!canScroll()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mVelocityTracker == null) {
|
||||
mVelocityTracker = VelocityTracker.obtain();
|
||||
@@ -468,25 +459,23 @@ public class ScrollView extends FrameLayout {
|
||||
final int deltaY = (int) (mLastMotionY - y);
|
||||
mLastMotionY = y;
|
||||
|
||||
if (deltaY < 0) {
|
||||
if (mScrollY > 0) {
|
||||
scrollBy(0, deltaY);
|
||||
}
|
||||
} else if (deltaY > 0) {
|
||||
final int bottomEdge = getHeight() - mPaddingBottom;
|
||||
final int availableToScroll = getChildAt(0).getBottom() - mScrollY - bottomEdge;
|
||||
if (availableToScroll > 0) {
|
||||
scrollBy(0, Math.min(availableToScroll, deltaY));
|
||||
}
|
||||
}
|
||||
super.scrollTo(mScrollX, mScrollY + deltaY);
|
||||
break;
|
||||
case MotionEvent.ACTION_UP:
|
||||
final VelocityTracker velocityTracker = mVelocityTracker;
|
||||
velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
|
||||
int initialVelocity = (int) velocityTracker.getYVelocity();
|
||||
|
||||
if ((Math.abs(initialVelocity) > mMinimumVelocity) && getChildCount() > 0) {
|
||||
fling(-initialVelocity);
|
||||
if (getChildCount() > 0) {
|
||||
if ((Math.abs(initialVelocity) > mMinimumVelocity)) {
|
||||
fling(-initialVelocity);
|
||||
} else {
|
||||
final int bottom = Math.max(0, getChildAt(0).getHeight() -
|
||||
(getHeight() - mPaddingBottom - mPaddingTop));
|
||||
if (mScroller.springback(mScrollX, mScrollY, 0, 0, 0, bottom)) {
|
||||
invalidate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mVelocityTracker != null) {
|
||||
@@ -915,14 +904,10 @@ public class ScrollView extends FrameLayout {
|
||||
int oldY = mScrollY;
|
||||
int x = mScroller.getCurrX();
|
||||
int y = mScroller.getCurrY();
|
||||
if (getChildCount() > 0) {
|
||||
View child = getChildAt(0);
|
||||
mScrollX = clamp(x, getWidth() - mPaddingRight - mPaddingLeft, child.getWidth());
|
||||
mScrollY = clamp(y, getHeight() - mPaddingBottom - mPaddingTop, child.getHeight());
|
||||
} else {
|
||||
mScrollX = x;
|
||||
mScrollY = y;
|
||||
}
|
||||
|
||||
mScrollX = x;
|
||||
mScrollY = y;
|
||||
|
||||
if (oldX != mScrollX || oldY != mScrollY) {
|
||||
onScrollChanged(mScrollX, mScrollY, oldX, oldY);
|
||||
}
|
||||
@@ -1159,7 +1144,8 @@ public class ScrollView extends FrameLayout {
|
||||
int height = getHeight() - mPaddingBottom - mPaddingTop;
|
||||
int bottom = getChildAt(0).getHeight();
|
||||
|
||||
mScroller.fling(mScrollX, mScrollY, 0, velocityY, 0, 0, 0, bottom - height);
|
||||
mScroller.fling(mScrollX, mScrollY, 0, velocityY, 0, 0, 0,
|
||||
Math.max(0, bottom - height), 0, height/2);
|
||||
|
||||
final boolean movingDown = velocityY > 0;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user