上篇blog介绍了ViewDragHelper的简单的使用,这篇blog再用ViewDragHelper来实现一个效果,先上图
再上代码:
public class BlackboardView extends ViewGroup {
private int mWidth;//控件的宽
private int mHeight;//控件的高
private View topView, bottonView, capturedView;
private ViewDragHelper mHelper;
private ViewDragHelper.Callback callback = new ViewDragHelper.Callback() {
@Override
public boolean tryCaptureView(View child, int pointerId) {
return (topView == child) || (bottonView == child);
}
@Override
public int clampViewPositionVertical(View child, int top, int dy) {
if (top < 0)
return 0;
if (top > mHeight / 2)
return mHeight / 2;
return top;
}
@Override
public int clampViewPositionHorizontal(View child, int left, int dx) {
return 0;
}
@Override
public void onViewReleased(View releasedChild, float xvel, float yvel) {
super.onViewReleased(releasedChild, xvel, yvel);
if (releasedChild.getTop() < mHeight / 4)
mHelper.smoothSlideViewTo(releasedChild, 0, 0);
else
mHelper.smoothSlideViewTo(releasedChild, 0, mHeight / 2);
ViewCompat.postInvalidateOnAnimation(BlackboardView.this);
}
@Override
public void onViewCaptured(View capturedChild, int activePointerId) {
super.onViewCaptured(capturedChild, activePointerId);
capturedView = capturedChild;
}
@Override
public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {
super.onViewPositionChanged(changedView, left, top, dx, dy);
if (changedView == capturedView) {
if (changedView == topView)
bottonView.offsetTopAndBottom(-dy);
else if (changedView == bottonView)
topView.offsetTopAndBottom(-dy);
}
}
};
public BlackboardView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public BlackboardView(Context context) {
super(context);
init();
}
public BlackboardView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
mHelper = ViewDragHelper.create(this, callback);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mWidth = getMeasuredWidth();
mHeight = getMeasuredHeight();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
for (int i = 0; i < getChildCount(); i++) {
measureChild(getChildAt(i), widthMeasureSpec, heightMeasureSpec);
}
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
topView = getChildAt(0);
bottonView = getChildAt(1);
topView.layout(0, 0, mWidth, mHeight / 2);
bottonView.layout(0, mHeight / 2, mWidth, mHeight);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return mHelper.shouldInterceptTouchEvent(ev);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
mHelper.processTouchEvent(event);
return true;
}
@Override
public void computeScroll() {
super.computeScroll();
if (mHelper.continueSettling(true)) {
ViewCompat.postInvalidateOnAnimation(this);
}
}
代码不难,比起上一篇blog,只是callback多2个回调函数,以及控制了两个子view的滑动。
public void onViewCaptured(View capturedChild, int activePointerId)
当滑动某一个子view时回调,down-move-up过程中只回调一次
public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy)
当子view位置变化时调用,不一定是拖动的那个。