您的位置:首页 > 其它

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

2016-02-05 20:23 253 查看
之前在公司开发的时候, 在主页部分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] /article/1562152.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: