ViewDragHelper一个帮助你轻松完成滑动操作的辅助类

本文介绍如何利用ViewDragHelper简化自定义ViewGroup中子View滑动的处理。通过实例展示了如何创建和配置ViewDragHelper,实现子View的拖拽、边界限制及边缘滑动等功能。
通过我们来处理自定义ViewGroup中子View滑动时,我们都是去通过事件拦截以及在onTouchEvent方法中进行手势判断,加速度检测等。

在官方的V4提供了ViewDragHelper来帮助我们方便的编写自定义ViewGroup时处理子View的滑动等相关的操作处理



代码演示:

public class CustomViewGroup extends ViewGroup {

    View childView_1; //子View1
    View childView_2; //子View2 
    ViewDragHelper viewDragHelper;

    public CustomViewGroup(Context context) {
        super(context);

        // 第一个参数为this,表示该类生成的对象,是ViewDragHelper的拖动处理对象,必须为ViewGroup。
        //第二个参数1.0f是敏感度参数参数越大越敏感,默认就是1.0f。
        //第三个参数回调接口,是ViewDragHelper与View交互的桥梁
        viewDragHelper = ViewDragHelper.create(this, 1.0f, new ViewDragHelper.Callback() {
            /**
             *通过DragHelperCallback的tryCaptureView方法的返回值可以决定一个parentview中哪个子view可以拖动,
             *
             * @param child
             * @param pointerId
             * @return
             */

            @Override
            public boolean tryCaptureView(View child, int pointerId) {
                //return child==childView_1; 如果如此 设置 只有 childView_1可以被ViewDragHelper控制
                return true; //所有View都可以
                //有人问 想 控制两个怎么办
                //return child == view1 || child == view2  >>>>>   484傻 ,其实是我问的
            }

            /**
             *该方法用来处理水平方向的滑动事件,返回目的值即可,但是为了处理例如边界情况,需要考虑到对象本身的边界值
             * @param child 需要被处理的对象  可以用此来判断(eg 只允许View1垂直滑动 ,判断一下,如果是view1我就不做任何操作不就行了么)
             * @param left 目的值(应该是以左边的点为依据)
             * @param dx
             * @return
             */
            @Override
            public int clampViewPositionHorizontal(View child, int left, int dx) {
                int left_bound = getPaddingLeft(); //左边的边界值
                int right_bound = getWidth() - getPaddingRight() - child.getWidth();//右边的边界值
                //这真是个有趣的表达式 第一步如果是左边部分的话,肯定是取值比 左边界要大,
                // 右边部分的话(肯定比左边界大了,内部的值Max取到的肯定是 left),取到的值要比右边界小
                //主要是为了 视图越界 呈现在手机窗口的外面了
                return Math.min(Math.max(left, left_bound), right_bound);
            }

            /*
            * 这里没有什么不同 只是垂直方向的罢了
            * */
            @Override
            public int clampViewPositionVertical(View child, int top, int dy) {
                int top_bound = getPaddingTop();//上边界
                int bottom_bound = getHeight() - getPaddingBottom() - child.getHeight();//下边界
                return Math.min(Math.max(top, top_bound), bottom_bound);
            }

            /**
             * 当设置了边缘滑动事件的时候,一旦事件发生,该方法就会被回调,要是想要相关View跟着运动需要在代码中执行
             * @param edgeFlags 边缘的滑动标志
             * @param pointerId
             */
            @Override
            public void onEdgeDragStarted(int edgeFlags, int pointerId) {
                //如此 第一个View就会跟着边缘事件进行 触发操作了
                viewDragHelper.captureChildView(childView_1, pointerId);

            }
        });


        //如果你想要处理左右边缘的滑动事件 可以通过以下设置 >>例如设置左边缘,如果想要监听到相关事件还需要重写回调中的一个方法
        //onEdgeDragStarted()
        viewDragHelper.setEdgeTrackingEnabled(ViewDragHelper.EDGE_LEFT);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        //该方法内部已经对相应的事件进行了过滤,至此直接将事件交给ViewDragHelper返回即可
        return viewDragHelper.shouldInterceptTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        //将事件拿到
        viewDragHelper.processTouchEvent(event);
        //表示消费该事件
        return true;
    }
    /**
     * 当View中所有的子控件 均被映射成xml后触发
     */
    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        //小心空指针呀,要是你布局文件里没有两个子View,不就GG了么 注意哈
        childView_1 = getChildAt(0);
        childView_2 = getChildAt(1);
    }
}

到此,我们的ViewDragHelper已经体验了一番,下一章,我们介绍剩下的几个特性,打造我们的侧滑菜单.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值