案例背景
侧滑菜单和主页的swipelayout出现冲突
效果类似于QQ的侧滑+消息列表
- sideMenu:顶级视图
- RecyclerView:列表视图
- swipelayout: 列表视图子视图
分析
在swipelayout向需要关闭的时候,事件被sideMenu消费了
- 手势被谁消费:sideMenu
- 要做的事情是:在sideMenu消费这个手势之前,判断swipelayout是否需要,如果需要,优先给swipelayout消费。
解决方式
方法一
- 重写RecyclerView所在的跟布局的onInterceptTouchEvent方法。在里面调用sideMenu的requestDisallowInterceptTouchEvent()
public boolean onInterceptTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
if(mAdapter!=null&&mAdapter.hasOpenItem())
//我将sideMenu的方法给homeActivty代理
homeActivity.requestDisallowInterceptTouchEvent(true);
else
homeActivity.requestDisallowInterceptTouchEvent(false);
break;
case MotionEvent.ACTION_MOVE:
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
if(mAdapter!=null&&mAdapter.hasOpenItem())
homeActivity.requestDisallowInterceptTouchEvent(true);
else
homeActivity.requestDisallowInterceptTouchEvent(false);
break;
}
return super.onInterceptTouchEvent(ev);
}
> 2.为swipelayout添加ontouchlistner,对事件进行处理
slItem.setOnTouchListener(touchListener);
View.OnTouchListener touchListener = new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
break;
case MotionEvent.ACTION_MOVE:
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
if (hasOpenItem()) closeAllItem();
break;
}
return false;
}};
方法二
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
startX =event.getX();
if(hasOpenItem())
activity.requestDisallowInterceptTouchEvent(true);
else
activity.requestDisallowInterceptTouchEvent(false);
break;
case MotionEvent.ACTION_MOVE:
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
float dx = event.getX()-startX;
LogUtils.i("nowy","dx: "+dx);
if (hasOpenItem()&&dx>0) {
closeAllItem();
return true;
}
}
return false;
}};
总结
- 处理这类型问题的时候,应该先明确谁把事件消费了,谁需要优先处理这个事件
- requestDisallowInterceptTouchEvent请求
- 然后事件就不会被父类先消费掉。