Android ViewDragHelper解析 实例练习

参考http://blog.csdn.net/lmj623565791/article/details/46858663

public class VDHLayout extends LinearLayout {

    private final ViewDragHelper mViewDragHelper;
    private View mDragView, mBackView, mEdgeTrackerView;
    private Point mPoint = new Point();

    public VDHLayout(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        mViewDragHelper = ViewDragHelper.create(this, 1.0f, new ViewDragHelper.Callback() {
            /**
             * tryCaptureView如何返回ture则表示可以捕获该view,你可以根据传入的第一个view参数决定哪些可以捕获
             */
            @Override
            public boolean tryCaptureView(View child, int pointerId) {
                return mDragView == child || mBackView == child;
            }

            /**
             * 水平方向可移动的范围
             * @param child
             * @param left
             * @param dx
             * @return
             */
            @Override
            public int clampViewPositionHorizontal(View child, int left, int dx) {
                final int leftBound = getPaddingLeft();
                final int rightBound = getWidth() - child.getWidth() - leftBound;

                final int newLeft = Math.min(Math.max(left, leftBound), rightBound);
                return newLeft;
            }

            /**
             * 垂直方向 可移动的范围
             * @param child
             * @param top
             * @param dy
             * @return
             */
            @Override
            public int clampViewPositionVertical(View child, int top, int dy) {
                return top;
            }

            /**
             * 手动释放后回调 settleCapturedViewAt回到初始的位置
             * @param releasedChild
             * @param xvel
             * @param yvel
             */
            @Override
            public void onViewReleased(View releasedChild, float xvel, float yvel) {
                if(releasedChild == mBackView){
                    mViewDragHelper.settleCapturedViewAt(mPoint.x,mPoint.y);
                    invalidate();
                }
            }

            /**
             * 在边界移动时 回调 
             * @param edgeFlags
             * @param pointerId
             */
            @Override
            public void onEdgeDragStarted(int edgeFlags, int pointerId) {
                //主动通过captureChildView对其进行捕获,该方法可以绕过tryCaptureView,
                // 所以我们的tryCaptureView虽然并为返回true,但却不影响。注意如果需要使用边界检测需要添加
                mViewDragHelper.captureChildView(mEdgeTrackerView,pointerId);
            }

            /**
             * 我们把我们的TextView全部加上clickable=true,意思就是子View可以消耗事件。再次运行,你会发现本来可以拖动的View不动了
             * 重写下面的两个方法 判断在水平或者垂直方向 是否可以捕获事件
             */
            @Override
            public int getViewHorizontalDragRange(View child) {
                return getMeasuredWidth()-child.getMeasuredWidth();
            }

            @Override
            public int getViewVerticalDragRange(View child)
            {
                return getMeasuredHeight()-child.getMeasuredHeight();
            }
        });
        mViewDragHelper.setEdgeTrackingEnabled(ViewDragHelper.EDGE_LEFT);//对左侧边界进行检测
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        return mViewDragHelper.shouldInterceptTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        mViewDragHelper.processTouchEvent(event);
        return true;
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
        
        //记录原来的位置
        mPoint.x = mBackView.getLeft();
        mPoint.y = mBackView.getTop();
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        mDragView = getChildAt(0);
        mBackView = getChildAt(1);
        mEdgeTrackerView = getChildAt(2);
        mDragView.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast.makeText(getContext(), "1111", Toast.LENGTH_SHORT).show();
            }
        });
    }

    /**
     * computeScroll和Scroller要是飞得拉关系的话,那就是computeScroll可以参考Scroller计算结果来影响scrollTo,scrollBy,
     * 从而使得滑动发生改变。也就是Scroller不会调用computeScroll,反而是computeScroll调用Scroller。
     */
    @Override
    public void computeScroll() {
        super.computeScroll();
        if(mViewDragHelper.continueSettling(true)){
            invalidate();
        }
    }
}

布局文件描述:




    

    

    


根据此练习可以了解ViewDragHelper类的基础用法

你可能感兴趣的:(Android ViewDragHelper解析 实例练习)