Android侧滑菜单和轮播图之滑动冲突问题
接手一个项目,有一个问题需要修改:轮播图不能手动滑动,手动滑动轮播图只会触发侧滑菜单。
猜测:viewpager控件(轮播图)的触摸事件被SlidingMenu控件(侧滑菜单,非第三方项目,乃是上个开发人员自定义的)拦截了。
基于这个猜测,我自定义一个ViewPager,重写dispatchTouchEvent、onInterceptTouchEvent和onTouchEvent,分别在这三个方法中打印log;
重写SlidingMenu的dispatchTouchEvent、onInterceptTouchEvent和onTouchEvent,同样打印log。
重新编译运行,手滑轮播图,log如下:
06-0809:52:08.39419424-19424/com.parkingmoreE/SlidingMenu:dispatchTouchEventev:0 06-0809:52:08.39519424-19424/com.parkingmoreE/SlidingMenu:onInterceptTouchEventev:0 06-0809:52:08.39519424-19424/com.parkingmoreE/RollViewPager:dispatchTouchEventev:0 06-0809:52:08.39519424-19424/com.parkingmoreE/RollViewPager:onInterceptTouchEventev:0 06-0809:52:08.44119424-19424/com.parkingmoreE/SlidingMenu:dispatchTouchEventev:2 06-0809:52:08.44119424-19424/com.parkingmoreE/SlidingMenu:onInterceptTouchEventev:2 06-0809:52:08.44219424-19424/com.parkingmoreE/SlidingMenu:ACTION_MOVEdx:15.473999 06-0809:52:08.44219424-19424/com.parkingmoreE/RollViewPager:ACTION_MOVEgetCurrentItem():1 06-0809:52:08.44219424-19424/com.parkingmoreE/RollViewPager:dispatchTouchEventev:2 06-0809:52:08.44219424-19424/com.parkingmoreE/RollViewPager:onInterceptTouchEventev:2 06-0809:52:08.45919424-19424/com.parkingmoreE/SlidingMenu:dispatchTouchEventev:2 06-0809:52:08.45919424-19424/com.parkingmoreE/SlidingMenu:onInterceptTouchEventev:2 06-0809:52:08.45919424-19424/com.parkingmoreE/RollViewPager:dispatchTouchEventev:3 06-0809:52:08.45919424-19424/com.parkingmoreE/RollViewPager:onInterceptTouchEventev:3 06-0809:52:08.47719424-19424/com.parkingmoreE/SlidingMenu:dispatchTouchEventev:2 06-0809:52:08.47719424-19424/com.parkingmoreE/SlidingMenu:onTouchEventev:2 06-0809:52:08.49519424-19424/com.parkingmoreE/SlidingMenu:dispatchTouchEventev:2 06-0809:52:08.49519424-19424/com.parkingmoreE/SlidingMenu:onTouchEventev:2 06-0809:52:08.51519424-19424/com.parkingmoreE/SlidingMenu:dispatchTouchEventev:2 06-0809:52:08.51519424-19424/com.parkingmoreE/SlidingMenu:onTouchEventev:2 06-0809:52:08.53319424-19424/com.parkingmoreE/SlidingMenu:dispatchTouchEventev:2 06-0809:52:08.53319424-19424/com.parkingmoreE/SlidingMenu:onTouchEventev:2 06-0809:52:08.55119424-19424/com.parkingmoreE/SlidingMenu:dispatchTouchEventev:2 06-0809:52:08.55119424-19424/com.parkingmoreE/SlidingMenu:onTouchEventev:2 06-0809:52:08.57419424-19424/com.parkingmoreE/SlidingMenu:dispatchTouchEventev:2 06-0809:52:08.57419424-19424/com.parkingmoreE/SlidingMenu:onTouchEventev:2 06-0809:52:08.59419424-19424/com.parkingmoreE/SlidingMenu:dispatchTouchEventev:2 06-0809:52:08.59519424-19424/com.parkingmoreE/SlidingMenu:onTouchEventev:2 06-0809:52:08.61119424-19424/com.parkingmoreE/SlidingMenu:dispatchTouchEventev:2 06-0809:52:08.61219424-19424/com.parkingmoreE/SlidingMenu:onTouchEventev:2 06-0809:52:08.62219424-19424/com.parkingmoreE/SlidingMenu:dispatchTouchEventev:2 06-0809:52:08.62219424-19424/com.parkingmoreE/SlidingMenu:onTouchEventev:2 06-0809:52:08.62319424-19424/com.parkingmoreE/SlidingMenu:dispatchTouchEventev:1
从log中可以看出,该开始,还能将滑动事件传递给ViewPager,之后,就被SlidingMenu拦截了。这个log证实了这个猜想是正确的。
知道了原因就好解决了,我现在要考虑的是:要达到什么样的效果。
预期效果:可以正常滑动轮播图,当轮播图在第一张时,可以滑到侧滑菜单。
网上有人分享过类似的问题。我这里也借鉴了一下。
先来实现第一个功能:可以正常滑动轮播图。
可以设一个全局变量:publicstaticbooleanmRollViewPagerTouching;
用来表示是否在触摸轮播图。
在自定义ViewPager中,判断是否在触摸轮播图
publicbooleandispatchTouchEvent(MotionEventev){
switch(ev.getAction()){
caseMotionEvent.ACTION_MOVE:
break;
caseMotionEvent.ACTION_DOWN:
MyApplication.mRollViewPagerTouching=true;
break;
caseMotionEvent.ACTION_UP:
MyApplication.mRollViewPagerTouching=false;
break;
}
returnsuper.dispatchTouchEvent(ev);
}
在SlidingMenu中,做出如下处理
publicbooleanonInterceptTouchEvent(MotionEventev){
if(MyApplication.mRollViewPagerTouching){
returnfalse;
}
returnsuper.onInterceptTouchEvent(ev);
}
重新编译运行,可以正常滑动轮播图,但是当轮播图在第一张时,不能滑到侧滑菜单。
现在来做第二个功能:当轮播图在第一张时,可以滑到侧滑菜单。
这里有两个地方要注意:1.当轮播图在第一张时;2.由于我的侧滑菜单是在左边,需要手指向右滑动进入侧滑菜单,所以,第二个条件,应该是右滑。
在以上的基础上,修改自定义ViewPager代码
publicbooleandispatchTouchEvent(MotionEventev){
//在触发时回去到起始坐标
floatx=ev.getX();
switch(ev.getAction()){
caseMotionEvent.ACTION_MOVE:
//获取到距离差
floatdx=x-downX;
//防止是按下也判断
if(Math.abs(dx)>8){
//通过距离差判断方向
if(dx>0){
//"右";
if(getCurrentItem()==0){
MyApplication.mRollViewPagerTouching=false;
}else{
MyApplication.mRollViewPagerTouching=true;
}
}else{
//"左";
MyApplication.mRollViewPagerTouching=true;
}
}
break;
caseMotionEvent.ACTION_DOWN:
//将按下时的坐标存储
downX=x;
MyApplication.mRollViewPagerTouching=true;
break;
caseMotionEvent.ACTION_UP:
MyApplication.mRollViewPagerTouching=false;
break;
}
returnsuper.dispatchTouchEvent(ev);
}
再次编译运行,成功达到预期效果。