参考http://blog.csdn.net/lmj623565791/article/details/46858663
public class VDHLayout extends LinearLayout {
private final ViewDragHelper mViewDragHelper;
private View mDragView, mBackView, mEdgeTrackerView;
private Point mPoint = new Point();
public VDHLayout(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
mViewDragHelper = ViewDragHelper.create(this, 1.0f, new ViewDragHelper.Callback() {
/**
* tryCaptureView如何返回ture则表示可以捕获该view,你可以根据传入的第一个view参数决定哪些可以捕获
*/
@Override
public boolean tryCaptureView(View child, int pointerId) {
return mDragView == child || mBackView == child;
}
/**
* 水平方向可移动的范围
* @param child
* @param left
* @param dx
* @return
*/
@Override
public int clampViewPositionHorizontal(View child, int left, int dx) {
final int leftBound = getPaddingLeft();
final int rightBound = getWidth() - child.getWidth() - leftBound;
final int newLeft = Math.min(Math.max(left, leftBound), rightBound);
return newLeft;
}
/**
* 垂直方向 可移动的范围
* @param child
* @param top
* @param dy
* @return
*/
@Override
public int clampViewPositionVertical(View child, int top, int dy) {
return top;
}
/**
* 手动释放后回调 settleCapturedViewAt回到初始的位置
* @param releasedChild
* @param xvel
* @param yvel
*/
@Override
public void onViewReleased(View releasedChild, float xvel, float yvel) {
if(releasedChild == mBackView){
mViewDragHelper.settleCapturedViewAt(mPoint.x,mPoint.y);
invalidate();
}
}
/**
* 在边界移动时 回调
* @param edgeFlags
* @param pointerId
*/
@Override
public void onEdgeDragStarted(int edgeFlags, int pointerId) {
//主动通过captureChildView对其进行捕获,该方法可以绕过tryCaptureView,
// 所以我们的tryCaptureView虽然并为返回true,但却不影响。注意如果需要使用边界检测需要添加
mViewDragHelper.captureChildView(mEdgeTrackerView,pointerId);
}
/**
* 我们把我们的TextView全部加上clickable=true,意思就是子View可以消耗事件。再次运行,你会发现本来可以拖动的View不动了
* 重写下面的两个方法 判断在水平或者垂直方向 是否可以捕获事件
*/
@Override
public int getViewHorizontalDragRange(View child) {
return getMeasuredWidth()-child.getMeasuredWidth();
}
@Override
public int getViewVerticalDragRange(View child)
{
return getMeasuredHeight()-child.getMeasuredHeight();
}
});
mViewDragHelper.setEdgeTrackingEnabled(ViewDragHelper.EDGE_LEFT);//对左侧边界进行检测
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return mViewDragHelper.shouldInterceptTouchEvent(ev);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
mViewDragHelper.processTouchEvent(event);
return true;
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
//记录原来的位置
mPoint.x = mBackView.getLeft();
mPoint.y = mBackView.getTop();
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
mDragView = getChildAt(0);
mBackView = getChildAt(1);
mEdgeTrackerView = getChildAt(2);
mDragView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(getContext(), "1111", Toast.LENGTH_SHORT).show();
}
});
}
/**
* computeScroll和Scroller要是飞得拉关系的话,那就是computeScroll可以参考Scroller计算结果来影响scrollTo,scrollBy,
* 从而使得滑动发生改变。也就是Scroller不会调用computeScroll,反而是computeScroll调用Scroller。
*/
@Override
public void computeScroll() {
super.computeScroll();
if(mViewDragHelper.continueSettling(true)){
invalidate();
}
}
}
布局文件描述:
<?xml version="1.0" encoding="utf-8"?>
<com.zhongxin.viewdraghelperdemo.VDHLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="match_parent"
>
<TextView
android:layout_margin="10dp"
android:gravity="center"
android:layout_gravity="center"
android:background="#44ff0000"
android:text="普通的"
android:layout_width="100dp"
android:layout_height="100dp"/>
<TextView
android:layout_margin="10dp"
android:layout_gravity="center"
android:gravity="center"
android:background="#44ff0000"
android:text="能返回的"
android:layout_width="100dp"
android:layout_height="100dp"/>
<TextView
android:layout_margin="10dp"
android:layout_gravity="center"
android:gravity="center"
android:background="#44ff0000"
android:text="沿着左侧边栏滑动"
android:layout_width="100dp"
android:layout_height="100dp"/>
</com.zhongxin.viewdraghelperdemo.VDHLayout>
根据此练习可以了解ViewDragHelper类的基础用法