学习笔记:Android ViewDragHelper的使用

来源:互联网 发布:相机双重曝光软件 编辑:程序博客网 时间:2024/05/21 06:47

学习笔记:Android ViewDragHelper的使用

参考博客:
【张鸿洋的博客】http : //blog.csdn.net/lmj623565791/article/details/46858663
我的代码的链接地址: https://pan.baidu.com/s/1boYX9Xd 密码: dihj

此处做个说明:本人也是Android初学者,对Android的知识理解不是很透彻,如果有什么错误的地方请多多谅解。

ViewDragHelper使用场景:

自定义ViewGroup的时候,经常会需要拖动其内部的控件,这时就需要重写onInterceptTouchEvent和onTouchEvent方法去实现。ViewDragHelper封装了对onInterceptTouchEvent和OnTouchEvent的处理,也就是说Google已经替我们写好了逻辑,我们只需要设定我们的UI动起来的轨迹就好了。

ViewDragHelper的使用:

1.创建ViewDragHelper,提供了一种工厂模式来创建:

helper=ViewDragHelper.create(viewGroup, new ViewDragHelper.Callback() {            @Override            public boolean tryCaptureView(View child, int pointerId) {                return false;            }        });

2.将触摸事件传递给ViewDragHelper。

  @Override    public boolean onTouchEvent(MotionEvent event) {        helper.processTouchEvent(event);        return true;    }    @Override    public boolean onInterceptTouchEvent(MotionEvent ev) {        return helper.shouldInterceptTouchEvent(ev);    }

3.重写ViewDragHelper.CallCack的相关方法

  helper = ViewDragHelper.create(this, new ViewDragHelper.Callback() {            @Override            public boolean tryCaptureView(View child, int pointerId) {               //设置哪些子View可以拖拽                return child == textView;            }            //getViewHorizontalDragRange和getViewVerticalDragRange方法是因为如果设置可以拖拽的子View可以响应点击等事件的话,这两个方法的返回值要大于0,才能同时响应点击事件和拖拽事件。            @Override            public int getViewHorizontalDragRange(View child) {                return getMeasuredWidth() - child.getMeasuredWidth();            }            @Override            public int getViewVerticalDragRange(View child) {                return getMeasuredHeight() - child.getMeasuredHeight();            }            @Override            public int clampViewPositionHorizontal(View child, int left, int dx) {                           //设置水平方向拖动的控件相对于父控件在x方向的坐标(这个方法一直没有弄清楚)                //left是拖动的控件相对于父控件在x方向的坐标,也就是距离父控件左边缘的距离                final int leftBound = getPaddingLeft();//拖动的控件的父控件距离左边缘的距离                final int rightBound = getWidth() - textView.getWidth() - leftBound;                final int newLeft = Math.min(Math.max(left, leftBound), rightBound);                return newLeft;            }            @Override            public int clampViewPositionVertical(View child, int top, int dy) {                //表示竖直方向的拖动范围不进行限制                return top;            }            //该方法在手指松开的时候调用            @Override            public void onViewReleased(View releasedChild, float xvel, float yvel) {                         super.onViewReleased(releasedChild, xvel, yvel);                    if (releasedChild == textView) {                    //point保存的是textView最开始相当于父控件的位置信息                    //追溯源码其实settleCapturedViewAt方法中使用的Scoller的startScroll和computeScroll方式进行平滑滑动的。所有这里要调用 invalidate()方法进行界面的重绘,且后面需重写computeScroll方法,调用 invalidate()重绘。                    helper.settleCapturedViewAt(point.x, point.y);                    invalidate();                }            }//            @Override//            public void onEdgeDragStarted(int edgeFlags, int pointerId) {//                //设置当拖动指定边缘的时候,哪个子View响应对应的拖拽。//                helper.captureChildView(getChildAt(1),pointerId);//            }        });        //设置哪个方向的边缘可以响应拖拽事件//        helper.setEdgeTrackingEnabled(ViewDragHelper.EDGE_LEFT);    }

注意:
1.在获取子控件的位置信息的时候,需要在onLayout方法中回去,这样才能确保已经测量完。

 @Override    protected void onLayout(boolean changed, int l, int t, int r, int b) {        super.onLayout(changed, l, t, r, b);        point.x = getChildAt(0).getLeft();        point.y = getChildAt(0).getTop();    }

2.在获取子View的实例的时候,需要在界面绘制完成之后,这样确保该控件已经绘制了,得到的实例才不会为null。

 @Override    protected void onFinishInflate() {        super.onFinishInflate();        textView = (TextView) getChildAt(0);    }
原创粉丝点击