Slidingmenu与ViewPager广告栏滑动冲突解决分享

之前在公司开发的时候, 在主页部分fragment使用了ViewPager作为广告栏,但项目里又引用了SlidingMenu开源库用作侧滑菜单,于是这里产生了滑动冲突:广告栏不能滑动了,滑动却是侧滑了SlidingMenu。

在这里我将我决解办法分享给大家,实现起来也十分简单。如果你不知道滑动事件分发,建议你先看下这个博客里写的,我觉得写得很精髓。
郭霖的博客: [Android事件分发机制完全解析,带你从源码的角度彻底理解(上)][1]


第一步,将SlidingMenu拷贝到自己项目中,而不是作为依赖库

之前我将SlidingMenu用作依赖库的形式导入项目,但是要修改SlidingMenu的源码的时候,发现一个问题,依赖库里拿不到我们自己包里的数据,可能是因为我比较丑,说不定可以有,但是我找不到。在qq群里问百度的任玉刚大神,他也说拿不到。。。
于是,好吧,没办法,把SlidingMenu直接复制到自己的项目中吧。
这里写图片描述

在这里,要将所有的文件全都拷贝到项目里,包括xml布局文件,自定义属性文件等。
这里写图片描述


第二步,写广告栏类里的事件拦截

首先要在application类里去增加一个变量,这个变量用于存储手势状态,以便SlidingMenu判断当前滑动的是广告栏,从而不去拦截事件。

public class LEPAppLication extends Application {

    public static boolean ImageCycleViewFlag;
    ...
}

接下来再广告栏类里去重写dispatchTouchEvent(MotionEvent event)方法

    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        int action = event.getAction();
        switch (action) {
            case MotionEvent.ACTION_DOWN:
                LEPAppLication.ImageCycleViewFlag = true;
                stopImageTimerTask();//停止自动轮播广告
                int index = MotionEventCompat.getActionIndex(event);
                mActivePointerId = MotionEventCompat.getPointerId(event, index);
                mLastMotionX = MotionEventCompat.getX(event, index);
                Log.d("debug", "拦截了ACTION_DOWN" + LEPAppLication.ImageCycleViewFlag);
                break;
            case MotionEvent.ACTION_MOVE:

                Log.d("debug", "拦截了ACTION_MOVE" + LEPAppLication.ImageCycleViewFlag);
                break;
            case MotionEvent.ACTION_UP:
                LEPAppLication.ImageCycleViewFlag = false;
                startImageTimerTask();
                Log.d("debug", "拦截了ACTION_UP" + LEPAppLication.ImageCycleViewFlag);
                break;
        }
        return super.dispatchTouchEvent(event);
    }

在上述代码中,当我们触摸到广告栏控件,便会让application里的ImageCycleViewFlag变量赋值true,当抬起手指,又让ImageCycleViewFlag变量赋值false。
这样,只要SlidingMenu判断这个ImageCycleViewFlag变量是否为true,就可以知道我们当前触摸的位置是不是广告栏了。


重写SlidingMenu里的 onInterceptTouchEvent(MotionEvent ev)方法

找到继承ViewGroup的类:CustomViewAbove。修改以下方法。

   @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {

        if (!mEnabled)
            return false;

        final int action = ev.getAction() & MotionEventCompat.ACTION_MASK;

        if (DEBUG)
            if (action == MotionEvent.ACTION_DOWN)
                Log.v(TAG, "Received ACTION_DOWN");

        if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP
                || (action != MotionEvent.ACTION_DOWN && mIsUnableToDrag)) {
            endDrag();
            return false;
        }

        switch (action) {
            case MotionEvent.ACTION_MOVE:
                determineDrag(ev);
                break;
            case MotionEvent.ACTION_DOWN:
                int index = MotionEventCompat.getActionIndex(ev);
                mActivePointerId = MotionEventCompat.getPointerId(ev, index);
                if (mActivePointerId == INVALID_POINTER)
                    break;
                mLastMotionX = mInitialMotionX = MotionEventCompat.getX(ev, index);
                mLastMotionY = MotionEventCompat.getY(ev, index);
                if (thisTouchAllowed(ev)) {
                    mIsBeingDragged = false;
                    mIsUnableToDrag = false;
                    if (isMenuOpen() && mViewBehind.menuTouchInQuickReturn(mContent, mCurItem, ev.getX() + mScrollX)) {
                        mQuickReturn = true;
                    }
                } else {
                    mIsUnableToDrag = true;
                }
                break;
            case MotionEventCompat.ACTION_POINTER_UP:
                onSecondaryPointerUp(ev);
                break;
        }

        if (!mIsBeingDragged) {
            if (mVelocityTracker == null) {
                mVelocityTracker = VelocityTracker.obtain();
            }
            mVelocityTracker.addMovement(ev);
        }
        return !LEPAppLication.ImageCycleViewFlag && (mIsBeingDragged || mQuickReturn);

    }

可以看到,修改的地方仅仅只有return的地方,没错,在ViewGroup里onInterceptTouchEvent方法返回true,则表示拦截事件,返回false表示不拦截,那么子View就可以拿到滑动事件。
当LEPAppLication.ImageCycleViewFlag为true时,那么这个方法永远返回false,那么广告栏控件就可以拿到触摸手势事件了。从而就可以滑动广告栏咯。
在广告栏的其他地方,又可以使用SlidingMenu侧滑。

希望对你有用。

[1] http://blog.csdn.net/guolin_blog/article/details/9097463

发布了48 篇原创文章 · 获赞 49 · 访问量 9万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 编程工作室 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览