+++++++++++++++++++++++++++++++方法1++++++++++++++++++++++++++++++++++++
activity_main.xml布局文件
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity" > <com.example.draghelper.CustomView android:layout_width="match_parent" android:layout_height="match_parent" > <View android:layout_width="100dp" android:layout_height="100dp" android:background="#FFFF0000" /> </com.example.draghelper.CustomView> </RelativeLayout>
package com.example.draghelper; import android.content.Context; import android.support.v4.widget.ViewDragHelper; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; import android.widget.LinearLayout; import android.widget.Toast; public class CustomView extends LinearLayout { private ViewDragHelper mDragHelper; private Context context; /**************************************************** * 三个构造器 */ public CustomView(Context context) { super(context); this.context = context; init(); } public CustomView(Context context, AttributeSet attrs) { super(context, attrs); this.context = context; init(); } public CustomView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); this.context = context; init(); } /** * @params ViewGroup forParent 一个ViewGroup, 也就是ViewDragHelper将要用来拖拽谁下面的子view * @params float sensitivity 灵敏度,一般1.0f即可 * @params Callback cb 一个回调,用来处理拖动到位置 */ private void init() { mDragHelper = ViewDragHelper.create(this, 1.0f, new ViewDragCallback()); } /** *表示尝试捕获子view,这里一定要返回true, 返回true表示允许。 *child 尝试捕获的view *@param int pointerId 指示器id? 这里可以决定哪个子view可以拖动 */ private class ViewDragCallback extends ViewDragHelper.Callback { @Override public boolean tryCaptureView(View view, int pointerId) { return true; } /******************************************************************** * 这两个方法分别用来处理x方向和y方向的拖动的,返回值该child现在的位置。 * @param View child 被拖动到view * @param int left 移动到达的x轴的距离 * @param int dx 建议的移动的x距离 * clampViewPositionHorizontal的第二个参数是指当前拖动子view应该到达的x坐标。 * 所以按照常理这个方法原封返回第二个参数就可以了,但为了让被拖动的view遇到边界之后就不在拖动,对返回的值做了更多的考虑 */ @Override public int clampViewPositionHorizontal(View child, int left, int dx) { Toast.makeText(context, "left = " + left + ", dx = " + dx, 0).show(); // 两个if主要是为了让viewViewGroup里 if (getPaddingLeft() > left) { return getPaddingLeft(); } if (getWidth() - child.getWidth() < left) { return getWidth() - child.getWidth(); } return left; } /** * 处理竖直方向上的拖动 * * @param View * child 被拖动到view * @param int top 移动到达的y轴的距离 * @param int dy 建议的移动的y距离 */ @Override public int clampViewPositionVertical(View child, int top, int dy) { // 两个if主要是为了让viewViewGroup里 if (getPaddingTop() > top) { return getPaddingTop(); } if (getHeight() - child.getHeight() < top) { return getHeight() - child.getHeight(); } return top; } /** * 当拖拽到状态改变时回调 * * @params 新的状态 */ @Override public void onViewDragStateChanged(int state) { switch (state) { case ViewDragHelper.STATE_DRAGGING: // 正在被拖动 break; case ViewDragHelper.STATE_IDLE: // view没有被拖拽 break; case ViewDragHelper.STATE_SETTLING: // fling完毕后被放置到一个位置 break; } super.onViewDragStateChanged(state); } } /**************************************************************** * 一但返回True(代表事件在当前的viewGroup中会被处理) */ @Override public boolean onInterceptTouchEvent(MotionEvent ev) { switch (ev.getAction()) { /** * 比如当你的手指在屏幕上拖动一个listView或者一个ScrollView而不是去按上面的按钮时会触发这个事件 */ case MotionEvent.ACTION_UP: case MotionEvent.ACTION_DOWN: mDragHelper.cancel(); // 类似onTouch的ACTION_UP事件,清除 break; } /** * 是否应该打断该MotionEvent的传递 */ return mDragHelper.shouldInterceptTouchEvent(ev); } @Override public boolean onTouchEvent(MotionEvent event) { /** * 处理拦截到的事件 这个方法会在返回前分发事件 */ mDragHelper.processTouchEvent(event); /** * return true 表示消费了事件。 */ return true; } }
DragLayout
package com.example.demo; import android.content.Context; import android.support.v4.widget.ViewDragHelper; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; import android.widget.RelativeLayout; public class DragLayout extends RelativeLayout { private final ViewDragHelper mDragHelper; final ViewDragHelper.Callback mDragCallBack = new ViewDragHelper.Callback() { @Override public int clampViewPositionHorizontal(View child, int left, int dx) { return left; }; @Override public int clampViewPositionVertical(View child, int top, int dy) { return top; }; @Override public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) { invalidate(); } /** * 通过DragHelperCallback的tryCaptureView方法的返回值可以决定一个parentview中哪个子view可以拖动 */ @Override public boolean tryCaptureView(View arg0, int arg1) { return true; } }; public DragLayout(Context context, AttributeSet attrs) { super(context, attrs); mDragHelper = ViewDragHelper.create(this, 1.0f, mDragCallBack); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { return mDragHelper.shouldInterceptTouchEvent(ev); } @Override public boolean onTouchEvent(MotionEvent event) { mDragHelper.processTouchEvent(event); return true; } }
++++++++++++++++++++方法3++++++++++++++++++++++++
http://blog.csdn.net/u013210620/article/details/46378231