Search code examples
androidandroid-scrollview

Android ScrollView bounce only while pulling down


I know there is an example how to implement the bounce effect on ScrollView, but here I am struggling whole day with one problem. I am creating something between Parallax ScrollView with bounce effect. Parallax ScrollView is taken from here : Parallax Android ScrollView and implements bounce effect on ObservableScrollView which now looks like this :

public class ObservableScrollView extends ScrollView {
private ScrollCallbacks mCallbacks;

private static final int MAX_Y_OVERSCROLL_DISTANCE = 150;

private Context mContext;
private int mMaxYOverscrollDistance;

public ObservableScrollView(Context context, AttributeSet attrs) {
    super(context, attrs);
    this.mContext = context;
    initBounceScrollView();
}

@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
    super.onScrollChanged(l, t, oldl, oldt);
    if (mCallbacks != null) {
        mCallbacks.onScrollChanged(l, t, oldl, oldt);
    }
}

@Override
public int computeVerticalScrollRange() {
    return super.computeVerticalScrollRange();
}

public void setCallbacks(ScrollCallbacks listener) {
    mCallbacks = listener;
}

private void initBounceScrollView() {
    // get the density of the screen and do some maths with it on the max
    // overscroll distance
    // variable so that you get similar behaviors no matter what the screen
    // size

    final DisplayMetrics metrics = mContext.getResources()
            .getDisplayMetrics();
    final float density = metrics.density;

    mMaxYOverscrollDistance = (int) (density * MAX_Y_OVERSCROLL_DISTANCE);

}

@Override
public void draw(Canvas canvas) {
    super.draw(canvas);
}

static interface ScrollCallbacks {
    public void onScrollChanged(int l, int t, int oldl, int oldt);
}

@SuppressLint("NewApi")
@Override
protected boolean overScrollBy(int deltaX, int deltaY, int scrollX,
        int scrollY, int scrollRangeX, int scrollRangeY,
        int maxOverScrollX, int maxOverScrollY, boolean isTouchEvent) {
    // This is where the magic happens, we have replaced the incoming
    // maxOverScrollY with our own custom variable mMaxYOverscrollDistance;
    return super.overScrollBy(deltaX, deltaY, scrollX, scrollY,
            scrollRangeX, scrollRangeY, maxOverScrollX,
            mMaxYOverscrollDistance, isTouchEvent);
}

Now the thing which I want to achieve is that bounce effect on parallax scrollview, but I want bounce effect should appear only when I am pulling down the ScrollView. For example when I am at the beginning of the ScrollView and pull it down. I want to disable bounce effect when I reach the end of ScrollView.

Any suggestions / ideas how can I achieve this..and is that the best way to create a custom View like this?


Solution

  • There is an onOverscrolled method introduced in api 9. You can achieve desired effect like this:

     @Override
        protected void onOverScrolled(int scrollX, int scrollY, boolean clampedX, boolean clampedY) {
            if (scrollY < 0)
                super.onOverScrolled(scrollX, scrollY, clampedX, clampedY);
        }
    

    So overscroll will happen only when you are pulling a scrollview down, and scrollY becomes negative. Switch it for (scrollY > 0) to achieve an opposite effect.