Skip to content

Instantly share code, notes, and snippets.

@pskink
Created May 18, 2015 07:52
Show Gist options
  • Save pskink/d7089e5a82c970917be1 to your computer and use it in GitHub Desktop.
Save pskink/d7089e5a82c970917be1 to your computer and use it in GitHub Desktop.
package com.example.app.myapplication;
import android.content.Context;
import android.support.v4.widget.ViewDragHelper;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
public abstract class FlexScrollView extends ViewGroup {
private static final String TAG = "FlexScrollView";
private final View mDragView;
private int mDeltaY;
public FlexScrollView(Context context) {
this(context, null, 0);
}
public FlexScrollView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public FlexScrollView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mDragView = new View(context);
addView(mDragView);
}
private ViewDragHelper.Callback mCallback = new ViewDragHelper.Callback() {
@Override
public int clampViewPositionVertical(View child, int top, int dy) {
top = Math.min(top, 0);
top = Math.max(top, getHeight() - child.getHeight());
return top;
}
@Override
public boolean tryCaptureView(View child, int pointerId) {
return child == mDragView;
}
@Override
public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {
mDeltaY -= dy;
requestLayout();
}
@Override
public void onViewCaptured(View capturedChild, int activePointerId) {
mDeltaY = 0;
}
@Override
public void onViewReleased(View releasedChild, float xvel, float yvel) {
mDragHelper.flingCapturedView(0, getHeight() - releasedChild.getHeight(), 0, 0);
invalidate();
}
};
private ViewDragHelper mDragHelper = ViewDragHelper.create(this, mCallback);
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
measureChildren(widthMeasureSpec, heightMeasureSpec);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
int action = ev.getAction();
if (action == MotionEvent.ACTION_MOVE && mDragHelper.checkTouchSlop(ViewDragHelper.DIRECTION_VERTICAL)) {
mDragHelper.captureChildView(mDragView, ev.getPointerId(0));
return true;
}
return mDragHelper.shouldInterceptTouchEvent(ev);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
mDragHelper.processTouchEvent(event);
return true;
}
@Override
public void computeScroll() {
boolean rc = mDragHelper.continueSettling(true);
if (rc) {
invalidate();
}
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
if (mDragView.getHeight() == 0) {
int h = getMaxHeight();
mDragView.layout(0, 0, getWidth(), h);
mDragView.bringToFront();
}
layoutChildren(-mDragView.getTop(), mDeltaY);
}
abstract public int getMaxHeight();
abstract public void layoutChildren(int yOffset, int yDelta);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment