ViewDragHelper是一个很好用但是也很难办的类。。。
先说下使用方法:
这个是用在view类中的,创建时传入当前view还有自己实现回调接口:
mHelper = ViewDragHelper.create(this, 1.0f, new ViewDragHelper.Callback()
{......}
下面就来说说这个接口里的方法:
有三个是必须实现的:
@Override
public int clampViewPositionHorizontal(View child, int left, int dx)
{
int newLeft = Math.max(-child.getWidth(), Math.min(left, 0));//范围:从-child.getWidth()到left
return newLeft;
}
@Override
public int getViewHorizontalDragRange(View child)
{
return mLeftMenuView == child ? child.getWidth() : 0;
}
上面这两个是返回边界值,举例:那个left参数就是你当前view理论上要达到的地方(此时你移动了他)
但是我们想让子view的移动有边界呀,你把我view扔出去了屏幕就回不来了。。。。
所以这里可以向上面一样巧妙处理一下,如果是在边界值内就让他放心移动,否则让他停在边界值 (clamp夹住,固定)
@Override
public boolean tryCaptureView(View child, int pointerId)
{
Log.e(“fish”,”tryCaptureView”);
return child == mLeftMenuView;
}
这个很好理解,就是你想捕捉哪些子view,如果当前这个view检测到被碰了就来判断一下。
然后还有几个是可以选做的,
@Override
public void onViewReleased(View releasedChild, float xvel, float yvel)
{
Log.e("fish","onViewReleased");
final int childWidth = releasedChild.getWidth();
float offset = (childWidth + releasedChild.getLeft()) * 1.0f / childWidth;
mHelper.settleCapturedViewAt(xvel > 0 || xvel == 0 && offset > 0.5f ? 0 : -childWidth, releasedChild.getTop());
invalidate();
}
这个很好理解,就是当view被放开的时候
结合后面这句:
mHelper.settleCapturedViewAt(x,y);就可以实现放开弹回的效果;上面那个例子就是判断一下有没有拖动过一半,再看要打开还是关闭;
@Override
public void onEdgeDragStarted(int edgeFlags, int pointerId)
{
Log.e("fish","onEdgeDragStarted");
mHelper.captureChildView(mLeftMenuView, pointerId);
}
边界拖动的时候调用;
还有,如果view内有点击事件,会消费掉事件,也就是拖不动。。
要写下这两个方法:
@Override
public int getViewHorizontalDragRange(View child) {
return getMeasuredWidth()-child.getMeasuredWidth();
}
@Override
public int getViewVerticalDragRange(View child) {
return getMeasuredHeight()-child.getMeasuredHeight();
}
其实只要返回一个大于零的数就行,这里的意思是说在控件以外的面板上移动都是有效的意思;
如果需要使用边界检测需要添加上mDragger.setEdgeTrackingEnabled(ViewDragHelper.EDGE_LEFT);
我们想拦截点击,这两个方法当然就要重写啦,但是免去了很多繁杂逻辑,全都交给helper就行:
@Override
public boolean onInterceptTouchEvent(MotionEvent event)
{
return mDragger.shouldInterceptTouchEvent(event);
}
@Override
public boolean onTouchEvent(MotionEvent event)
{
mDragger.processTouchEvent(event);
return true;
}
哦别忘了,不断的重绘,否则画面是黑的,亲身试验了= =
@Override
public void computeScroll()
{
if(mDragger.continueSettling(true))
{
invalidate();
}
}
本片参考文章:
鸿洋—— ViewDragHelper实战 自己打造Drawerlayout
http://blog.csdn.net/lmj623565791/article/details/47396187
鸿洋—— Android ViewDragHelper完全解析 自定义ViewGroup神器
http://blog.csdn.net/lmj623565791/article/details/46858663
谢谢观看~