ViewDragHelper 使用

最近需要写自定义ViewGroup,发现直接写事件处理很麻烦使用ViewDragHelper处理就很简单,ViewDragHelper是用来处理子view的事件处理工具:

在onMeasure(int widthMeasureSpec, int heightMeasureSpec)中需要做子view的测量和自己的测量:

@Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int width = MeasureSpec.getSize(widthMeasureSpec);
        int height = MeasureSpec.getSize(heightMeasureSpec);
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        //测量子view的大小
        measureChildren(widthMeasureSpec, heightMeasureSpec);
        if (heightMode == MeasureSpec.AT_MOST) {
            height = getChildAt(0).getMeasuredHeight();
        }
        //设置自己的宽高
        setMeasuredDimension(width, height);
        // super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

在onLayout(boolean changed, int l, int t, int r, int b)中做子view的位子布局设置:

@Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
    //int l, int t, int r, int b参数为自己的范围,即布局的矩形范围
        Log.e("onLayout", "int l, int t, int r, int b=" + l + ":" + t + ":" + r + ":" + b);
        final int count = getChildCount();
        int xpos = getPaddingLeft();
        int ypos = getPaddingTop();
        for (int i = 0; i < count; i++) {
            final View child = getChildAt(i);
            if (child.getVisibility() != GONE) {
            //调用layout确认子view的位置
                child.layout(xpos + i * space, ypos, xpos + i * space + child.getMeasuredWidth(),
                        ypos + child.getMeasuredHeight());
            }
        }
    }

重写onTouchEvent(MotionEvent event)处理子view的事件处理(也可以重写onInterceptTouchEvent(MotionEvent ev)去拦截事件等)

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

ViewDragHelper的创建,重写一些需要的方法:

mViewDragHelper = ViewDragHelper.create(this, 1.0f, new ViewDragHelper.Callback() {

            @Override
            public boolean tryCaptureView(View view, int arg1) {//判断自view是否能捕获(能否移动)

                return true;
            }

            @Override
            public int clampViewPositionHorizontal(View view, int left, int dx) {
                int count = getChildCount();
                int index = indexOfChild(view);
                //计算边界[a,b]
                int a = index * space;
                int b = a;
                if (index >0) {
                    b = getMeasuredWidth() - (count - index) * space;
                }
                left = Math.max(a, Math.min(left, b));
                return left;
            }
        });

    }

这样就能简单的水平移动

弹性滑动的实现:

调用:

在ViewDragHelper 回调中调用 (应为这是设置CapturedView)
//fling设置两个边界一个是轻滑动,一个是重滑动
mViewDragHelper.flingCapturedView();
mViewDragHelper.settleCapturedViewAt();

或者调用:

smoothSlideViewTo(View child, int finalLeft, int finalTop)

注意需要在布局中实现:

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

参考连接:Android ViewDragHelper完全解析 自定义ViewGroup神器

猜你喜欢

转载自blog.csdn.net/kingyc123456789/article/details/53068949
今日推荐