ViewDragHelper

来源:互联网 发布:ppt怎么修改图表数据 编辑:程序博客网 时间:2024/04/27 23:16
效果图:
ss
一、概述
ViewDragHelper is a utility class for writing custom ViewGroups. It offers a number of useful operations and state tracking for allowing a user to drag and reposition views within their parent ViewGroup.
官方的解释:在自定义ViewGroup时,ViewDragHelper可以用来拖拽和设置子View的位置(在ViewGroup范围内)。另外,还提供了一系列的方法和状态跟踪。在自定义ViewGroup时,ViewDragHelper一般用来处理子View的位置移动。
原理:通过在ViewGroup中拦截、处理事件,根据事件内容改变ViewGroupe的位置,将这些逻辑和效果进行封装就成了ViewDragHelper类

二、入门小示例
首先我们通过一个简单的例子来看看其快捷的用法,分为以下几个步骤:
1、自定义ViewGroup
2、创建ViewDragHelper实例并关联ViewGroup,设置callBack
3、处理事件

public class VDHLayout extends LinearLayout{
private ViewDragHelper mDragger;
public VDHLayout(Context context, AttributeSet attrs) {
super(context, attrs); 
mDragger = ViewDragHelper.create(this,1.0f,new ViewDragHelper.Callback() 
{
@Override
publicboolean tryCaptureView(View child,int pointerId) {
return true;
}
@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 boolean onInterceptTouchEvent(MotionEvent event) {
return mDragger.shouldInterceptTouchEvent(event);
}
@Override
publicboolean onTouchEvent(MotionEvent event) {
mDragger.processTouchEvent(event);
returntrue;
}
}


可以看到,上面整个自定义ViewGroup的代码非常简洁,遵循上述3个步骤:
1、创建实例
mDragger = ViewDragHelper.create(this,1.0f,new ViewDragHelper.Callback() { ..});
创建实例需要3个参数:第一个就是当前的ViewGroup;第二个sensitivity,主要用于设置touchSlop:
helper.mTouchSlop = (int) (helper.mTouchSlop * (1 / sensitivity)),传入越大,mTouchSlop的值就会越小;第三个参数就是Callback,在用户的触摸过程中会回调相关方法,后面会细说。

2、触摸相关方法
@Override
public boolean onInterceptTouchEvent(MotionEventevent) {
return mDragger.shouldInterceptTouchEvent(event);
}

@Override
public boolean onTouchEvent(MotionEventevent) {
mDragger.processTouchEvent(event);
return true;
}
onInterceptTouchEvent中通过使用mDragger.shouldInterceptTouchEvent(event)来决定我们是否应该拦截当前的事件。onTouchEvent中通过mDragger.processTouchEvent(event)处理事件。

3、实现ViewDragHelper.CallCack相关方法
new ViewDragHelper.Callback() {
@Override
public boolean tryCaptureView(View child,int pointerId) {
return true;
}

@Override
public int clampViewPositionHorizontal(View child,int left,int dx) {
return left;
}

@Override
public int clampViewPositionVertical(View child,int top,int dy) {
return top;
} }

ViewDragHelper中拦截和处理事件时,需要会回调CallBack中的很多方法来决定一些事,比如:哪些子View可以移动、对个移动的View的边界的控制等等。
上面复写的3个方法:
tryCaptureView如何返回ture则表示可以捕获该view,你可以根据传入的第一个view参数决定哪些可以捕获:
例如:return child == 你要进行拖拽的View

clampViewPositionHorizontal,clampViewPositionVertical可以在该方法中对child移动的边界进行控制,left , top 分别为即将移动到的位置,
如果横向的情况下,你希望只在ViewGroup的内部移动,即:最小>=paddingleft,最大<=ViewGroup.getWidth()-paddingright-child.getWidth。就可以按照如下代码编写:

@Override
publicint clampViewPositionHorizontal(View child,int left,int dx) {
final int leftBound = getPaddingLeft();
final int rightBound = getWidth() - mDragView.getWidth() - leftBound;
final int newLeft = Math.min(Math.max(left, leftBound), rightBound);
return newLeft;
}


注意:当给View设置点击事件时发现View移动不了了,这时候要在DragerHelper的CallBack里面处理点击事件:
 @Override
public int getViewHorizontalDragRange(View child) {
//可以对child进行判断
    return getMeasuredWidth()-child.getMeasuredWidth();
}

@Override
public int getViewVerticalDragRange(View child) {
     return getMeasuredHeight()-child.getMeasuredHeight();
}


转载于:
http://blog.csdn.net/lmj623565791/article/details/46858663; 
原创粉丝点击