SwipeBackLayout 滑动返回与垂直滚动优化

app要加入右滑返回上个界面的功能,百度了一下,发现这个库不错,https://github.com/ikew0ng/SwipeBackLayout,于是集成到app里面。

在跑这个demo的时候,发现返回的时候看到的是桌面,并非上个界面,百度一下,发现很多人遇到这个问题,于是加入这个代码到要返回的activity的主题里即可

<item name= "android:windowIsTranslucent" >true </item>
但这个库支持右滑返回的接触面只在左侧,虽然有setEdgeSize设置宽度,但好像不是很有效,百度一下

//http://blog.csdn.net/eiuly/article/details/46472783
    private int getEdgeTouched(int x, int y) {
        result = EDGE_LEFT;//这样每次都是全屏左滑删除
        return result;
    }
  这样果然可以全屏右滑返回了,但在测试的时候发现某些界面用到了popupwidow,弹框的时候设置了其他地方变黑的遮罩,导致整个activity的界面不见了,百度无果,于是只能把popupwindow改成alertdialog来解决了。

 改好后看起来一切都OK了,但测试的时候又发现一个问题,5.5寸屏幕的手机操作起来还可以,但在我新买的小米5(5.15寸)黑色版本上操作起来的时候,在有垂直滚动的界面单手滚动界面的时候很容易触发侧滑操作,这就尴尬了。百度无果,于是只能自己解决了。

  查看SwipeBackLayout代码,有onInterceptTouchEvent事件分发函数,找来笔记本,画了一下操作手势图。

开始的时候根据垂直距离与水平的滑动距离来判断事件的拦截,但效果一点也不理想,于是想到用角度来判断胡奥的滑动的意图。两点与XY轴形成的三角形的夹角如果大于45°(我自己想的)就判定为垂直滚动的,否则就是侧滑返回。理论有了就敲代码,幸好以前算过三角函数,计算两点的角度代码

   float a = xDistance;//a边
   float b = yDistance;//b边
   double c = Math.sqrt(a * a + b * b);//c边,斜边
   double Q = Math.asin(b / c);//a、b边的夹角度数(Q / Math.PI * 180这个才是人类常用的角度)
<pre style="font-family: Consolas; font-size: 11.3pt; background-color: rgb(255, 255, 255);">于是加入判断

                if (Math.abs(Q / Math.PI * 180) > 45 && mDragState == STATE_IDLE && 0 != xDistance) {
                    return false;
                }
测试一下代码,发现可行。
附上ViewDragHelper文件修改地方的代码
    // 滑动距离及坐标
    private float xDistance, yDistance, xLast, yLast;
    /**
     * Check if this event as provided to the parent view's
     * onInterceptTouchEvent should cause the parent to intercept the touch
     * event stream.
     *
     * @param ev MotionEvent provided to onInterceptTouchEvent
     * @return true if the parent view should return true from
     * onInterceptTouchEvent
     */
    public boolean shouldInterceptTouchEvent(MotionEvent ev) {
        final int action = MotionEventCompat.getActionMasked(ev);
        final int actionIndex = MotionEventCompat.getActionIndex(ev);

        if (action == MotionEvent.ACTION_DOWN) {
            // Reset things for a new event stream, just in case we didn't get
            // the whole previous stream.
            cancel();
        }

        if (mVelocityTracker == null) {
            mVelocityTracker = VelocityTracker.obtain();
        }
        mVelocityTracker.addMovement(ev);

        switch (action) {
            case MotionEvent.ACTION_DOWN: {
                xDistance = yDistance = 0f;
                xLast = ev.getX();
                yLast = ev.getY();
                final float x = ev.getX();
                final float y = ev.getY();
                final int pointerId = MotionEventCompat.getPointerId(ev, 0);
                saveInitialMotion(x, y, pointerId);

                final View toCapture = findTopChildUnder((int) x, (int) y);

                // Catch a settling view if possible.
                if (toCapture == mCapturedView && mDragState == STATE_SETTLING) {
                    tryCaptureViewForDrag(toCapture, pointerId);
                }

                final int edgesTouched = mInitialEdgeTouched[pointerId];
                if ((edgesTouched & mTrackingEdges) != 0) {
                    mCallback.onEdgeTouched(edgesTouched & mTrackingEdges, pointerId);
                }
                break;
            }

            case MotionEventCompat.ACTION_POINTER_DOWN: {
                final int pointerId = MotionEventCompat.getPointerId(ev, actionIndex);
                final float x = MotionEventCompat.getX(ev, actionIndex);
                final float y = MotionEventCompat.getY(ev, actionIndex);

                saveInitialMotion(x, y, pointerId);

                // A ViewDragHelper can only manipulate one view at a time.
                if (mDragState == STATE_IDLE) {
                    final int edgesTouched = mInitialEdgeTouched[pointerId];
                    if ((edgesTouched & mTrackingEdges) != 0) {
                        mCallback.onEdgeTouched(edgesTouched & mTrackingEdges, pointerId);
                    }
                } else if (mDragState == STATE_SETTLING) {
                    // Catch a settling view if possible.
                    final View toCapture = findTopChildUnder((int) x, (int) y);
                    if (toCapture == mCapturedView) {
                        tryCaptureViewForDrag(toCapture, pointerId);
                    }
                }
                break;
            }

            case MotionEvent.ACTION_MOVE: {
                final float curX = ev.getX();
                final float curY = ev.getY();

                xDistance += Math.abs(curX - xLast);
                yDistance += Math.abs(curY - yLast);
                xLast = curX;
                yLast = curY;

                float a = xDistance;//a边
                float b = yDistance;//b边
                double c = Math.sqrt(a * a + b * b);//c边,斜边
                double Q = Math.asin(b / c);//a、b边的夹角度数(Q / Math.PI * 180这个才是人类常用的角度)
                if (Math.abs(Q / Math.PI * 180) > 45 && mDragState == STATE_IDLE && 0 != xDistance) {
                    Log.i("xiang:", "xDistance-" + xDistance + "  yDistance-" + yDistance + "角度-"+Q / Math.PI * 180);
                    return false;
                }
                // First to cross a touch slop over a draggable view wins. Also
                // report edge drags.
                final int pointerCount = MotionEventCompat.getPointerCount(ev);
                for (int i = 0; i < pointerCount; i++) {
                    final int pointerId = MotionEventCompat.getPointerId(ev, i);
                    final float x = MotionEventCompat.getX(ev, i);
                    final float y = MotionEventCompat.getY(ev, i);
                    final float dx = x - mInitialMotionX[pointerId];
                    final float dy = y - mInitialMotionY[pointerId];

                    reportNewEdgeDrags(dx, dy, pointerId);
                    if (mDragState == STATE_DRAGGING) {
                        // Callback might have started an edge drag
                        break;
                    }

                    final View toCapture = findTopChildUnder((int) x, (int) y);
                    if (toCapture != null && checkTouchSlop(toCapture, dx, dy)
                            && tryCaptureViewForDrag(toCapture, pointerId)) {
                        break;
                    }
                }
                saveLastMotion(ev);
                break;
            }

            case MotionEventCompat.ACTION_POINTER_UP: {
                final int pointerId = MotionEventCompat.getPointerId(ev, actionIndex);
                clearMotionHistory(pointerId);
                break;
            }

            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL: {
                cancel();
                break;
            }
        }

        return mDragState == STATE_DRAGGING;
    }


 



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值