美文网首页
ViewDragHelper的使用

ViewDragHelper的使用

作者: Endeav0r | 来源:发表于2018-12-21 15:26 被阅读10次

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);

参阅:

相关文章

网友评论

      本文标题:ViewDragHelper的使用

      本文链接:https://www.haomeiwen.com/subject/yqamkqtx.html