模拟360手机卫士界面的滑动

前一篇文章写了怎么模拟桌面的滑动,这里分享一个模拟360安全卫士的滑动,主要是因为在网上看到有人问九宫格界面的滑动处理。

因为这样的界面里面有几个大大的块,这些块有点击事件,所以当在这个方块上面按下再左右滑动的时候,界面就不会跟着滑动了,因为这个事件已经被传递给滑动界面的子view了,滑动界面已经不再做出响应了。

解决的方法我参考了viewpager的源代码,自己做了简化,在原来模拟桌面滑动的代码基础上,完成了这个效果,效果图如下:

第一张图是滑动的效果,第二张图是点击的效果。

 

实现的方法就是重写onInterceptTouchEvent这个方法,这个方法的返回值表示当前的view要不要拦截用户的点击事件,true表示拦截,false表示不拦截,如果返回true则子view就不能得到点击事件。

这里不能简单的返回true或者false,因为我们需要拦截的是左右滑动的事件,而不是简单的点击事件,所以当用户的事件是一个简单的点击事件时就交给它的子view,如果是左右滑动的事件,则做拦截。

代码如下。

 

 @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        mIsScorlling = false;
        final int action = ev.getAction() & MotionEvent.ACTION_MASK;
        if (action == MotionEvent.ACTION_CANCEL
                || action == MotionEvent.ACTION_UP) {
            mIsScorlling = false;
            return false;
        }
       
        switch (action) {
        case MotionEvent.ACTION_DOWN:
            mActivePointerId = ev.getPointerId(0);
            mLastMotionX = ev.getX();
            mIsScorlling = false;
            break;
        case MotionEvent.ACTION_MOVE:
            final int pointerIndex = ev.findPointerIndex(mActivePointerId);
            try {
                final float x = ev.getX(pointerIndex);
                final float deltaX = mLastMotionX - x;
                mLastMotionX = x;
                final float absDeltaX = Math.abs(deltaX);
                if (absDeltaX > 6) {
                    mIsScorlling = true;
                }
            } catch (ArrayIndexOutOfBoundsException e) {
               
            }
            break;
        }
        return mIsScorlling;
    }

 

这个较上一版的改动还有 如果滑到最后一个,就不能再往后划,如果在第一个,就不能往前滑,判断代码如下:

float downX = -1;

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        final int action = ev.getAction();
        switch (action & MotionEvent.ACTION_MASK) {
        case MotionEvent.ACTION_DOWN:
            mLastMotionX = ev.getX();
            mActivePointerId = ev.getPointerId(0);
            downX = mLastMotionX;
            break;
        case MotionEvent.ACTION_MOVE:

            final int pointerIndex = ev.findPointerIndex(mActivePointerId);
            try {
                final float x = ev.getX(pointerIndex);
                final float deltaX = mLastMotionX - x;
                mLastMotionX = x;
                if (deltaX > 0) {
                    if (mCurrentViewIndex >= getChildCount() - 1) {
                        return true;
                    }
                    scrollBy((int) deltaX, 0);
                } else if (deltaX < 0) {
                    if (mCurrentViewIndex <= 0) {
                        return true;
                    }
                    scrollBy((int) deltaX, 0);
                } else {
                    awakenScrollBars();
                }
            } catch (ArrayIndexOutOfBoundsException e) {

            }
            break;
        case MotionEvent.ACTION_UP:
            int screenWidth = getWidth();
            int whichView = (getScrollX() + (screenWidth / 2)) / screenWidth;
            whichView = Math.max(0, Math.min(whichView, getChildCount() - 1));
            int newX = whichView * getWidth();
            int delta = newX - getScrollX();
            mScroller.startScroll(getScrollX(), 0, delta, 0,
                    Math.abs(delta) * 2);
            invalidate();
            mCurrentViewIndex = whichView;
            if (mViewIndexChangeLinstener != null) {
                mViewIndexChangeLinstener.onIndexChange(whichView);
            }
            break;
        case MotionEvent.ACTION_CANCEL:
            break;
        case MotionEvent.ACTION_POINTER_UP:
            break;
        }
        return true;
    }

 

还有就是为了能让这个控件灵活地通知当前的索引,就是滑到第几个界面了,我将原来调用activity的静态方法改成通过回调的方式,代码如下:

 public interface ViewIndexChangeLinstener {
        public void onIndexChange(int whichView);
    }

    public void setViewIndexChangeLinstener(ViewIndexChangeLinstener linstener) {
        this.mViewIndexChangeLinstener = linstener;
    }

这个只是简单的提一下实现的方法,具体代码等我上传以后,在评论里面给出下载地址。

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值