一、
one。 通过改变view 在父空间的layout位置来移动, 但是只能移动指定的view:
view.layout(l,t,r,b);
view.offsetLeftAndRight(offset);
view.offsetTopAndBottom(offset);
two。通过改变scrollX 和 scrollY 来移动, 但是 可以移动所有的子view
scrollTo(x,y); x,y 将要滚动到的位置
scrollBy(xOffset,yOffset); 滚动的偏移量
three。通过改变canvas 绘制的位置来移动view 的内容(不常用)
canvas.drawBitmap(bitmap,l,t,paint);
二、使用ViewDragHelper来处理移动
one。ViewDragHelper 在 support v4中 如要导入v4包
two。主要用于处理ViewGroup中对子View的拖拽处理
three。在Google2013年大会中提出
four。主要封装了对View的触摸位置,触摸速度,移动距离等的检测和Scroller,
five。本质是对触摸事件的解析类
通过接口回调的方式告诉我们;只需要我们指定是否需要移动,移动多少等。
use:forParent 父View sensitivity 敏感度 默认为1.0f cb 回调接口
ViewDragHelper mViewDragHelper=ViewDragHelper.create(
ViewGroup forParent, float sensitivity, Callback cb
)
如果使用ViewDragHelper 需要重写两个事件
// 拦截触摸事件
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return mViewDragHelper.shouldInterceptTouchEvent(ev);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
// 处理拖拽事件
mViewDragHelper.processTouchEvent(event);
return true;
} /**
* 回调
*/
private class MyCallBack extends ViewDragHelper.Callback {
/**
* * 用于判断是否捕捉当前 child 的触摸事件
*
* @param child 当前触摸的子View
* @param pointerId 尝试捕获id 的 指针
* @return true 捕获别切 解析 false 不处理
*/
@Override
public boolean tryCaptureView(View child, int pointerId) {
return child == redView || child == blueView;
}
/**
* 当view 被开始捕获和解析的回调 用处不太大
*
* @param capturedChild 当前被捕获的子View
* @param activePointerId
*/
@Override
public void onViewCaptured(View capturedChild, int activePointerId) {
super.onViewCaptured(capturedChild, activePointerId);
}
/**
* 获取view 水平方向的拖范围 但是目前不能限制边界,
* 在 clampViewPositionHorizontal 计算实现
* 返回的值用在手指抬起的时候,view缓慢移动的动画的时间计算上面
*
* @param child
* @return 最好不要返回 0
*/
@Override
public int getViewHorizontalDragRange(View child) {
return getMeasuredWidth() - child.getMeasuredWidth();
}
/**
* 获取view 垂直方向的拖范围 但是目前不能限制边界,
* 在 clampViewPositionVertical 计算实现
* 返回的值用在手指抬起的时候,view缓慢移动的动画的时间计算上面
*
* @param child
* @return 最好不要返回 0
*/
@Override
public int getViewVerticalDragRange(View child) {
return getMeasuredHeight() - child.getMeasuredHeight();
}
/**
* 控制child在 水平方向的移动 clamp ->修正
*
* @param child
* @param left 表示ViewDragHelper 认为你想让当前child的left改变的值
* left=child.getLeft() + dx;
* @param dx 相对于 控件移动前,水平移动的距离
* 负数为向左边移动正数为向右边移动
* @return 表示真正你想让child的left 改变成的值
*/
@Override
public int clampViewPositionHorizontal(View child, int left, int dx) {
// 如果不想让view 水平移动 return left - dx 或者 child.getLeft();
return left;
}
/**
* 控制child在 垂直方向的移动 clamp ->修正
*
* @param child
* @param top 表示ViewDragHelper 认为你想让当前child的top改变的值
* top=child.getTop() + dy;
* @param dy 相对于 控件移动前,水平移动的距离
* 负数为向左边移动正数为向右边移动
* @return 表示你真正想让child的top 改变成的值
*/
@Override
public int clampViewPositionVertical(View child, int top, int dy) {
return top;
}
/**
* 当child 位置改变的时候执行 一般用来做其它子view 的伴随移动
*
* @param changedView 位置改变的 child
* @param left child 当前最新的left
* @param top child 当前最新的top
* @param dx 本次水平移动的距离 因为每一次滑动都不一样
* @param dy 本次垂直移动的距离 为每一次滑动都不一样
*/
@Override
public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {
}
/**
* 当手指抬起的时候会执行这个方法
*
* @param releasedChild 当前抬起的view
* @param xvel x方向移动的速度 正 向右移动 负数 向左移动
* @param yvel y方向移动的速度 正 向右移动 负数 向左移动
*/
@Override
public void onViewReleased(View releasedChild, float xvel, float yvel) {
super.onViewReleased(releasedChild, xvel, yvel);
if (releasedChild.getLeft() > getMeasuredWidth() / 2 - releasedChild.getMeasuredWidth() / 2) {
// 在右边 向右边缓慢移动 移动 view 到右边
mViewDragHelper.smoothSlideViewTo(releasedChild,
getMeasuredWidth() - releasedChild.getMeasuredWidth(), releasedChild.getTop());
ViewCompat.postInvalidateOnAnimation(DragLayout.this);
} else {
// 在左边 向左边缓慢移动
mViewDragHelper.smoothSlideViewTo(releasedChild, 0, releasedChild.getTop());
ViewCompat.postInvalidateOnAnimation(DragLayout.this);
}
}
}
/**
* 计算滚动 配合 mViewDragHelper.smoothSlideViewTo(releasedChild, 0, releasedChild.getTop());
* 一直刷新界面
*/
@Override
public void computeScroll() {
// 如果继续移动 刷新界面
if (mViewDragHelper.continueSettling(true)) {
ViewCompat.postInvalidateOnAnimation(DragLayout.this);
}
}
共同学习,写下你的评论
评论加载中...
作者其他优质文章