ViewDragHelper的使用,关键代码已做注释。
public class KeyBoardViewDragLayout extends LinearLayout {
private ViewDragHelper mViewDragHelper = null;
private int duration;
private GridView mGridView;
private LinearLayout mKeyBoardLayout;
private int mKeyBoardLayoutHeight;
private int totalHeight;
private int mGridViewHeight;
private int srcTop;
public KeyBoardViewDragLayout(Context context) {
this(context, null);
}
public KeyBoardViewDragLayout(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public KeyBoardViewDragLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
createVDH();
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
L.show("onLayout grid height==" + mGridView.getMeasuredHeight());
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
mGridView = findViewById(R.id.mPayGridView);
mKeyBoardLayout = findViewById(R.id.mKeyBoardLayout);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
totalHeight = getMeasuredHeight();
mKeyBoardLayoutHeight = mKeyBoardLayout.getMeasuredHeight();
mGridViewHeight = mGridView.getMeasuredHeight();
srcTop = totalHeight - mKeyBoardLayoutHeight;
L.show("srcTop==" + srcTop);
L.show("totalHeight==" + totalHeight);
L.show("mGridViewHeight==" + mGridViewHeight);
L.show("mKeyBoardLayoutHeight==" + mKeyBoardLayoutHeight);
}
public void createVDH() {
// 通过ViewDragHelper.create方法创建实例。
DraggerCallBack callBack = new DraggerCallBack();
mViewDragHelper = ViewDragHelper.create(this, 1.0f, callBack);
}
public OnDragChangeListener mOnDragListener;
public interface OnDragChangeListener {
void onDrag(int duration);
}
public void setOnDragChangeListener(OnDragChangeListener l) {
if (l != null) mOnDragListener = l;
}
class DraggerCallBack extends ViewDragHelper.Callback {
@Override
public boolean tryCaptureView(@NonNull View view, int i) {
// 返回true代表改子view可以被拖动
return view == mKeyBoardLayout;
}
@Override
public int clampViewPositionVertical(View child, int top, int dy) {
// top:相对于Y轴的x坐标,负数代表向上拖拽
if (top < srcTop) {
top = srcTop;// 控制只能向下滑
}
return top;
}
// 拖拽范围,默认是0,需重写
@Override
public int getViewVerticalDragRange(@NonNull View child) {
return child.getMeasuredHeight();
}
// 手指离开后调用,可以实现view消失和回弹效果,需结合重写computeScroll()方法
@Override
public void onViewReleased(@NonNull View releasedChild, float xvel, float yvel) {
if (duration < mKeyBoardLayoutHeight / 3) {
mViewDragHelper.settleCapturedViewAt(0, srcTop);//参数:子view相对于父
postInvalidate();
} else {
// settleCapturedViewAt貌似只能在该类使用
mViewDragHelper.settleCapturedViewAt(0, totalHeight);//参数:子view相对于父
postInvalidate();
}
}
// 位置发生变化时调用,在使用时发现这个方法不一定就是上面指定的view
@Override
public void onViewPositionChanged(@NonNull View changedView, int left, int top, int dx, int dy) {
LinearLayout.LayoutParams layoutParams = (LayoutParams) mKeyBoardLayout.getLayoutParams();
// 键盘 - 滑动距离
layoutParams.height = mKeyBoardLayoutHeight - top + totalHeight - mKeyBoardLayoutHeight;
mKeyBoardLayout.setLayoutParams(layoutParams);
duration += dy;
L.show("KeyBoardLayout PositionChanged duration==" + duration + ",dy==" + dy);
if (mOnDragListener != null) mOnDragListener.onDrag(duration);
}
}
public void dragIn() {
if (!isKeyboardShowing()) {
// smoothSlideViewTo滑动到指定位置
if (mViewDragHelper.smoothSlideViewTo(mKeyBoardLayout, 0, srcTop)) {
ViewCompat.postInvalidateOnAnimation(this);
postInvalidate();
}
}
}
public void dragOut() {
if (isKeyboardShowing()) {
if (mViewDragHelper.smoothSlideViewTo(getChildAt(0), 0, totalHeight)) {
ViewCompat.postInvalidateOnAnimation(this);
postInvalidate();
}
}
}
public boolean isKeyboardShowing() {
return duration == 0;
}
@Override
public void computeScroll() {
if (mViewDragHelper.continueSettling(true)) {
ViewCompat.postInvalidateOnAnimation(this);
}
}
// 必须重写
@Override
public boolean onTouchEvent(MotionEvent event) {
dragHelper.processTouchEvent(event);
return true;
}
}
补充回调接口中的一个其它方法:
// 该方法可以绕过tryCaptureView()方法,在该方法中主动捕获view
@Override
public void onEdgeDragStarted(int edgeFlags, int pointerId) {
dragHelper.captureChildView(edgeDragView, pointerId);
}
// 结合onEdgeDragStarted(),设置左边缘可以被Drag
dragHelper.setEdgeTrackingEnabled(ViewDragHelper.EDGE_LEFT);
参阅:
网友评论