您的位置:首页 > 其它

解决SlidingMenu与ViewPager的滑动冲突尝试

2016-05-23 23:48 423 查看
模仿唯品会侧边栏与viewpager场景,尝试解决SlidingMenu与ViewPager的滑动冲突。

SlidingMenu使用张鸿洋大神的自定义控件。

参考:http://blog.csdn.net/lmj623565791/article/details/39257409

效果如下:



代码讲解:

采用内部拦截法,slidingmenu先不拦截事件,让事件传到viewpager。

@Override
public boolean onInterceptHoverEvent(MotionEvent event)
{
int action = event.getAction();
if(action == MotionEvent.ACTION_DOWN){
return false;
}else{
return true;
}
}


如果只看上面的代码的话,只有ACTION_DOWN事件传递到子view,但是子view可以通过设置requestDisallowInterceptTouchEvent(true);阻止父层拦截事件,后面也可以看到子view在ACTION_DOWN时设置该方法为true,所以尽管父层是想拦截除DOWN之外的其它事件,也没办法吧。

viewpager获得事件,在对事件分发时对滑动进行判断,当为第0个界面并且依然向右滑动时,将事件交还给slidingmenu。

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
int x = (int) ev.getX();
int y = (int) ev.getY();

switch (ev.getAction()){
case MotionEvent.ACTION_DOWN:
getParent().requestDisallowInterceptTouchEvent(true);
break;
case MotionEvent.ACTION_MOVE:

if(!scrollable){
getParent().requestDisallowInterceptTouchEvent(false);
break;
}
int deltaX = x - mLastX;
if( getCurrentItem()==0 && deltaX >0 ){
getParent().requestDisallowInterceptTouchEvent(false);
}
break;
case MotionEvent.ACTION_UP:
break;
}

mLastX = x;
mLastY = y;
return super.dispatchTouchEvent(ev);
}


其中有个布尔值scrollable,当slidingmenu打开时,scrollable设为false,此时viewpager一定会把所有的事件交给slidingmenu。即通过scrollable控制是否阻止父层拦截事件,从而决定事件是被slidingMenu拦截还是传到viewpager。

case MotionEvent.ACTION_MOVE:
if(!scrollable){
getParent().requestDisallowInterceptTouchEvent(false);
break;
}


而当slidingmenu关闭时,再把scrollable设为true,则一切又回到最初的样子,形成一个循环,问题是viewpager并不知道slidingmenu什么时候关闭,slidingmenu也不能设置viewpager的属性,所有只能交给于两者都有关联的activity处理,让activity监听slidingmenu的打开和关闭,然后设置viewpager的scrollable。

public interface SlidingMenuListener {

void open();
void close();
}

// 在activity中监听slidingMenu的打开和关闭操作
slidingMenu.setSlidingMenuListener(new SlidingMenuListener() {
@Override
public void open() {
viewPager.setScrollable(false);
}

@Override
public void close() {
viewPager.setScrollable(true);
}
});


slidingmenu在滑动的实现中回调:

@Override
public boolean onTouchEvent(MotionEvent ev)
{
int action = ev.getAction();
switch (action)
{
// Up时,进行判断,如果显示区域大于菜单宽度一半则完全显示,否则隐藏
case MotionEvent.ACTION_UP:
int scrollX = getScrollX();
if (scrollX > mHalfMenuWidth)
{
this.smoothScrollTo(mMenuWidth, 0);
isOpen = false;
Logger.i("关闭");
listener.close();
} else
{
this.smoothScrollTo(0, 0);
isOpen = true;
Logger.i("打开");
listener.open();
}
return true;
}
return super.onTouchEvent(ev);
}


感觉像是一个简单的有限状态机,总是可以在一个循环中回到原点。

源码链接:解决SlidingMenu和ViewPager的滑动冲突
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: