关于从边测划出控件

原创 2016年05月31日 17:22:02
最近使用滴滴打车,因为要打印发票才发现原来滴滴打车还有个侧边栏,不过不能划开,需要点击打开。估计是因为和里面的地图冲突,所以才这么设计的。于是自己实现了个小的控件去进行了改善。主要思想就是监听滑动事件,如果是在边上则当前的view处理,如果超过了边缘则传递给子view去处理。后面又发现了viewDragerhelper这个东东,于是更简单了~
public class MyView extends ViewGroup {
    private ViewDragHelper mDragger;
    //被滑动的view
    private View mDragView;
    //边缘是否被触摸
    private boolean isEdgeTouched;
    //监听滑动速度
    private VelocityTracker vTracker = null;
    //是否打开
    private boolean isOpen;
    //自定义属性,可以打开的距离
    float cap;

    public MyView(Context context, AttributeSet attrs) {
        super(context, attrs);
        TypedArray a = context.obtainStyledAttributes(attrs,
                R.styleable.MyView);
        int n = a.getIndexCount();
        for (int i = 0; i < n; i++) {
            int attr = a.getIndex(i);
            switch (attr) {
                case R.styleable.MyView_cap:
                    //获得可以打开的距离,转化为px单位
                    cap = a.getDimensionPixelSize(attr, 250);
            }
        }
        a.recycle();
        mDragger = ViewDragHelper.create(this, 1.0f, new ViewDragHelper.Callback() {

            @Override
            public boolean tryCaptureView(View child, int pointerId) {
                //只有边缘被触摸,才返回滑动的view
                if (isEdgeTouched)
                    return mDragView == child;
                else
                    return false;
            }

            @Override
            public int clampViewPositionHorizontal(View child, int left, int dx) {
                final int leftBound = getPaddingLeft();
                return Math.min(Math.max(left, leftBound), getWidth() - (int) cap);
            }

            @Override
            public void onEdgeDragStarted(int edgeFlags, int pointerId) {
                isEdgeTouched = true;
                mDragger.captureChildView(mDragView, pointerId);
            }

            //手指释放的时候回调
            @Override
            public void onViewReleased(View releasedChild, float xvel, float yvel) {
                if (releasedChild == mDragView) {
                    //如果正向滑动,没有打开并且速度大于每秒5,直接打开view                    if (xvel > 5 && !isOpen) {
                        //这里以自定义属性gap为打开的距离
                        mDragger.settleCapturedViewAt(getWidth() - (int) cap, getTop());
                        invalidate();
                        isOpen = true;
                        return;
                    }
                    //如果负向滑动,已经打开并且速度大于每秒5,直接关闭view                    if (xvel < -5 && isOpen) {
                        mDragger.settleCapturedViewAt(0, getTop());
                        isEdgeTouched = false;
                        invalidate();
                        isOpen = false;
                        return;
                    }
                    //判断滑动的距离是否超过最大距离的一半,有则打开
                    if (mDragView.getLeft() > (getWidth() - cap) / 2) {
                        mDragger.settleCapturedViewAt(getWidth() - (int) cap, getTop());
                        invalidate();
                        isOpen = true;
                        return;
                    }
                    //判断滑动的距离是否小于等于最大距离的一半,是则关闭
                    if (mDragView.getLeft() <= (getWidth() - cap) / 2) {
                        mDragger.settleCapturedViewAt(0, getTop());
                        isEdgeTouched = false;
                        invalidate();
                        isOpen = false;
                        return;
                    }
                }
            }
        });
        mDragger.setEdgeTrackingEnabled(ViewDragHelper.EDGE_LEFT);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        int count = this.getChildCount();

        for (int i = 0; i < count; i++) {
            View child = this.getChildAt(i);

            child.measure(widthMeasureSpec, heightMeasureSpec);

        }
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        for (int i = 0, size = getChildCount(); i < size; i++) {
            if (i == 0) {
                View view = getChildAt(i);
                view.layout(left, top, right - (int) cap, bottom);
            } else {
                View view = getChildAt(i);
                view.layout(left, top, right, bottom);
                mDragView = view;
            }
        }
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        //如果view打开了,则当前view处理滑动事件,也就是说view打开后可以通过手势滑回去,把关注点放在打开的view        if (isOpen) {
            return true;
        } else
            return mDragger.shouldInterceptTouchEvent(event);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (vTracker == null) {
            vTracker = VelocityTracker.obtain();
        } else {
            vTracker.clear();
        }
        //监听滑动速度,以每秒多少个像素为单位
        vTracker.addMovement(event);
        vTracker.computeCurrentVelocity(1000);//10001000毫秒
        mDragger.processTouchEvent(event);
        return true;
    }

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

}

android 从底部划出Dialog

我是根据大神学习的,这个是大神的项目,这个项目里面含有我标题所叙述的,我只是学习到这里,感觉比较好,所以提炼出来,现在我给出大神的gitHub https://github.com/robotlif...
  • u013125680
  • u013125680
  • 2016年05月17日 20:00
  • 836

JavaScript 鼠标划入划出

鼠标移入移出 My lovely Heburn. var over = document.getElementById('over'); var heburn ...
  • cyanciel
  • cyanciel
  • 2016年12月27日 20:17
  • 633

侧边工具条实现 scss+requirejs(3)

为返回顶部按钮完善全部功能,深度定制 在封装一个backtop.js模块,并且引用scrollTo模块,完成返回顶部按钮的隐藏消失以及返回功能 // 未返回顶部按钮深度定制一个模块,包括显示隐藏和回到...
  • realDE
  • realDE
  • 2017年02月20日 09:42
  • 447

jquery实现居中、左下角、右下角窗口效果

jquery_windows.html文件 弹出窗口 $(document).ready(function (){ //利用toggle方法实现显示和隐藏 $(...
  • zhaoxinglei0309
  • zhaoxinglei0309
  • 2012年03月27日 21:07
  • 2158

Jqery 划入划出等特效

1.jQuery 拥有以下滑动方法:       slideDown()   划出       slideUp()     划入         slideToggle()  划出 划入切换   例:...
  • zhizhuo0915
  • zhizhuo0915
  • 2017年11月30日 09:52
  • 87

PopupWindow从底部划入划出

1.动画animation_in.xml:
  • fuzhongbin
  • fuzhongbin
  • 2016年04月07日 18:32
  • 582

测边交会

目 录 第1章 计算公式    1 1.1 排列顺序    1 1.2 计算公式一    2 1.3 排列顺序的判定    3 1.4 计...
  • Hanford
  • Hanford
  • 2016年12月15日 09:36
  • 206

运放高边电流检测

转自:http://www.devlabs.cn/?p=308 看到一个运放做的高边电流检测, 感觉很巧妙, 于是仿真了一下, 负载不变, 使用恒流源将电流从0上升到100mA,下图中蓝为仿真结果曲...
  • rookiew
  • rookiew
  • 2015年06月20日 11:37
  • 1777

从逻辑分区中划出主分区

从逻辑分区中划出主分区背景:我最近准备在一台安装了WindowsXP 的机器上,再装一个其他操作系统,当然这个操作系统和微软没有任何关系。在查阅了很多资料后,得知该操作系统的安装有如下的要求。首先,操...
  • VisionCat
  • VisionCat
  • 2005年12月28日 17:34
  • 6213

从考试成绩中划出及格线

/****************************************************************** 个学生考完期末试评卷成后,老师需要划出及格线,求如下: (1)及...
  • walkerkalr
  • walkerkalr
  • 2014年03月21日 20:43
  • 1545
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:关于从边测划出控件
举报原因:
原因补充:

(最多只允许输入30个字)