您的位置:首页 > 其它

ViewDragHelper拖拽----类似天天静听拖拽隐藏歌词界面

2016-10-15 17:00 239 查看

前言

对于不熟悉ViewDragHelper的同学可以参考一下鸿洋大神的点击这里,这里只是发布利用ViewDragHelper的实际开发DEMO。

先上效果图



直接贴代码

public class ViewDragLayout extends LinearLayout {

/**
* headview在头部
*/
private static final int TOP = 0;
/**
* headview在底部
*/
private static final int BOTTOM = 1;
//初始化headview在头部
private int state = TOP;
private ViewDragHelper viewDragHelper;
//速度跟踪
private VelocityTracker tracker;
//头布局
private View mHeadView;
//主布局
private View mDescriView;

//拖拽速度
private float speed;
//纵向移动范围
int mDragRange;

//纵向移动比例
float mDragOffset;

//距离顶部的 top
int mTop;

public ViewDragLayout(Context context, AttributeSet attrs) {
super(context, attrs);

viewDragHelper = ViewDragHelper.create(this, callback);

}

//回调
ViewDragHelper.Callback callback = new ViewDragHelper.Callback() {

//纵向拖动
@Override
public int clampViewPositionVertical(View child, int top, int dy) {
//不能超过顶部
return Math.max(top, 0);
}

//横向拖动
@Override
public int clampViewPositionHorizontal(View child, int left, int dx) {

return super.clampViewPositionVertical(child, left, dx);

}

//返回值要大于0,否则无法拖动
@Override
public int getViewVerticalDragRange(View child) {
return mDragRange;
}

//位置发生改变时候的回调
@Override
public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {
//记录距离顶部的距离
mTop = top;
mDragOffset = (float) top / mDragRange;
mHeadView.setPivotX(mHeadView.getWidth());
mHeadView.setPivotY(mHeadView.getHeight());

//缩放和透明度
mHeadView.setScaleX(1 - mDragOffset / 2);
mHeadView.setScaleY(1 - mDragOffset / 2);
mDescriView.setAlpha(1 - mDragOffset);
requestLayout();
}

//松开的时候
@Override
public void onViewReleased(View releasedChild, float xvel, float yvel) {

//拽图中的view 的中点距离顶部的top
int centerPoint = mTop + releasedChild.getHeight() / 2;

if (state == TOP) {//处于顶部的时候
//拖动大于一半 或者速度大于100
if (centerPoint > getHeight() / 2 || speed > 100) {

viewDragHelper.settleCapturedViewAt(releasedChild.getLeft(), getHeight() - releasedChild.getHeight());
//headview到了底部
state = BOTTOM;
} else {//回归

viewDragHelper.settleCapturedViewAt(releasedChild.getLeft(), 0);

}

} else if (state == BOTTOM) {//处于底部的时候
//拖动大于一半 或者速度大于100
if (centerPoint < getHeight() / 2 || speed < -100) {

viewDragHelper.settleCapturedViewAt(releasedChild.getLeft(), 0);

//headview回到头部
state = TOP;

} else {//回归

viewDragHelper.settleCapturedViewAt(releasedChild.getLeft(), getHeight() - releasedChild.getHeight());

}

}
//重新执行onLayout
requestLayout();

}

@Override
public boolean tryCaptureView(View child, int pointerId) {

//只有headview能拖动
return child == mHeadView;
}
};

@Override
protected void onFinishInflate() {
super.onFinishInflate();
mHeadView = getChildAt(0);
mDescriView = getChildAt(1);

}

@Override
public void computeScroll() {
if (viewDragHelper.continueSettling(true)) {
invalidate();
}
}

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);

//上下滑动的范围
mDragRange = getHeight() - mHeadView.getHeight();

mHeadView.layout(0, mTop, r, mTop + mHeadView.getMeasuredHeight());

mDescriView.layout(0, mTop + mHeadView.getMeasuredHeight(), r, mTop + b);

}

//事件交给ViewDragHelper
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return viewDragHelper.shouldInterceptTouchEvent(ev);
}

//事件交给ViewDragHelper
@Override
public boolean onTouchEvent(MotionEvent event) {

switch (event.getAction()) {

case MotionEvent.ACTION_DOWN:

if (tracker == null) {
//获取速度跟踪器
tracker = VelocityTracker.obtain();
}
break;

case MotionEvent.ACTION_MOVE:

//获取滑动的速度
tracker.addMovement(event);
tracker.computeCurrentVelocity(1000);

speed = tracker.getXVelocity();

break;

case MotionEvent.ACTION_UP:
try {
//释放上次的跟踪
tracker.clear();
tracker.recycle();
tracker = null;
} catch (Exception e) {

}
break;
}
viewDragHelper.processTouchEvent(event);
return true;
}
}


end

代码上的注释已经很详细,ViewDragHelper比起自己从头到尾用event事件的处理方便多了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  自定义 界面