Slidingmenu与ViewPager广告栏滑动冲突解决分享
2016-02-05 20:23
253 查看
之前在公司开发的时候, 在主页部分fragment使用了ViewPager作为广告栏,但项目里又引用了SlidingMenu开源库用作侧滑菜单,于是这里产生了滑动冲突:广告栏不能滑动了,滑动却是侧滑了SlidingMenu。
在这里我将我决解办法分享给大家,实现起来也十分简单。如果你不知道滑动事件分发,建议你先看下这个博客里写的,我觉得写得很精髓。
郭霖的博客: [Android事件分发机制完全解析,带你从源码的角度彻底理解(上)][1]
于是,好吧,没办法,把SlidingMenu直接复制到自己的项目中吧。
在这里,要将所有的文件全都拷贝到项目里,包括xml布局文件,自定义属性文件等。
接下来再广告栏类里去重写dispatchTouchEvent(MotionEvent event)方法
在上述代码中,当我们触摸到广告栏控件,便会让application里的ImageCycleViewFlag变量赋值true,当抬起手指,又让ImageCycleViewFlag变量赋值false。
这样,只要SlidingMenu判断这个ImageCycleViewFlag变量是否为true,就可以知道我们当前触摸的位置是不是广告栏了。
可以看到,修改的地方仅仅只有return的地方,没错,在ViewGroup里onInterceptTouchEvent方法返回true,则表示拦截事件,返回false表示不拦截,那么子View就可以拿到滑动事件。
当LEPAppLication.ImageCycleViewFlag为true时,那么这个方法永远返回false,那么广告栏控件就可以拿到触摸手势事件了。从而就可以滑动广告栏咯。
在广告栏的其他地方,又可以使用SlidingMenu侧滑。
希望对你有用。
[1] /article/1562152.html
在这里我将我决解办法分享给大家,实现起来也十分简单。如果你不知道滑动事件分发,建议你先看下这个博客里写的,我觉得写得很精髓。
郭霖的博客: [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] /article/1562152.html
相关文章推荐
- HDU 2108 Shape of HDU(数学公式)
- NumPy基础(一)
- Twitter将推算法时间线
- eval解析JSON注意点
- WM_PAINT中应该用BeginPaint与EndPaint这两个api,它们的功能正是使无效区域恢复(所以WM_PAINT里即使什么都不做,也必须写上BeginPaint与EndPaint)——Delphi里WM_PAINT消息的三个走向都做到了这一点
- win10下如何快速安装迷你迅雷
- 学习kmp算法
- hdu 5619 Jam's store (mcmf)
- Exercise1_3_37
- HDU3047带权并查集
- 算法_2:数值算法
- Cloud Design Patterns: Prescriptive Architecture Guidance for Cloud Applications 云设计模式:云应用的规范架构指导
- 队列
- Open Credit System
- 线索二叉树
- HDU 1247 Hat’s Words
- WM_PAINT消息详解,使用InvalidateRect或InvalidateRgn函数刻意产生WM_PAINT消息(WIN7里有变化,“调整视觉效果”,将“启用桌面组合”去掉)
- Scanf函数的输入问题
- NSWindow.setFrame的坑
- HTML5开发移动web应用——Sencha Touch篇(8)