实现思路:
- 创建拖动范围和拖动控件
- 实现拖动控件的可拖动效果,通过OnTouchListener实现
- 限制拖动范围为边界
- 实现左右两边停靠,并添加动画返回效果
首先实现可拖动的功能:
dragView.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
lastX = (int) event.getRawX();
lastY = (int) event.getRawY();
break;
case MotionEvent.ACTION_MOVE:
int mTop = dragView.getTop();
int mLeft = dragView.getLeft();
int mBottom = dragView.getBottom();
int mRight = dragView.getRight();
//X轴拖动的距离
int slideX = (int) (event.getRawX() - lastX);
//Y轴拖动的距离
int slideY = (int) (event.getRawY() - lastY);
if (mTop < 0) {
mTop = 0;
mBottom = dragView.getHeight();
}
int rootHeight = getHeight();
int rootWidth = getWidth();
//为上下左右做边界限制
if (mBottom > rootHeight) {
mBottom = rootHeight;
mTop = rootHeight - dragView.getHeight();
}
//这里的hideSize为隐藏到边界外的部分,设置为0则悬浮框完整显示
if (mLeft < -hideSize) {
mLeft = -hideSize;
mRight = dragView.getWidth() - hideSize;
}
if (mRight > rootWidth + hideSize) {
mRight = rootWidth + hideSize;
mLeft = rootWidth - dragView.getWidth() + hideSize;
}
dragView.layout(mLeft + slideX, mTop + slideY, mRight + slideX, mBottom + slideY);
lastX = (int) event.getRawX();
lastY = (int) event.getRawY();
break;
然后再在拖动结束之后判断位置 向左右移动
case MotionEvent.ACTION_UP:
int leftLimit = (getWidth() - dragView.getWidth()) / 2;
//在最中间的时候动画所需最大执行时间
int maxDuration = 500;
int duration;
if (dragView.getLeft() < leftLimit) {
//根据距离边界的距离,弹性计算动画执行时间,防止距离边界很近的时候执行时间仍是过长
duration = maxDuration * (dragView.getLeft() + hideSize) / (leftLimit + hideSize);
animSlide(dragView, dragView.getLeft(), -hideSize, duration);
} else {
duration = maxDuration * (getWidth() + hideSize - dragView.getRight()) / (leftLimit + hideSize);
animSlide(dragView, dragView.getLeft(), getWidth() - dragView.getWidth() + hideSize, duration);
}
break;
滑动增加动画效果
private void animSlide(final View view, final int leftFrom, int leftTo, int duration) {
ValueAnimator valueAnimator = ValueAnimator.ofInt(leftFrom, leftTo);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
int viewLeft = (int) valueAnimator.getAnimatedValue();
view.layout(viewLeft, view.getTop(), viewLeft + view.getWidth(), view.getBottom());
}
});
//为防止溢出边界时,duration时间为负值,做下0判断
valueAnimator.setDuration(duration < 0 ? 0 : duration);
valueAnimator.start();
}
直接代码,好使给个star谢谢