如何避免Navigation Drawer中水平RecyclerView左滑时关闭抽屉?
这个问题我之前做项目时也踩过坑,核心就是要让水平RecyclerView把触摸事件“吃”掉,别让它传到Navigation Drawer那里去。给你两个实用的解决办法:
方法一:通过OnTouchListener拦截事件传递
直接给你的RecyclerView设置触摸监听器,在触摸开始时阻止父布局(Navigation Drawer)拦截事件,触摸结束后再恢复,这样RecyclerView就能独自处理水平滑动了:
mNavigationRecyclerHourly.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View view, MotionEvent motionEvent) { switch (motionEvent.getAction()) { case MotionEvent.ACTION_DOWN: // 告诉父布局:这个触摸事件我要自己处理,别抢 view.getParent().requestDisallowInterceptTouchEvent(true); break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: // 触摸结束,恢复父布局的拦截能力,不影响抽屉正常关闭逻辑 view.getParent().requestDisallowInterceptTouchEvent(false); break; } // 让RecyclerView自己处理触摸事件(比如滑动、点击) view.onTouchEvent(motionEvent); return true; } });
方法二:自定义RecyclerView实现全局拦截
如果你的项目里有多个这样的水平RecyclerView,自定义一个RecyclerView会更优雅,不用每次都写重复的监听器:
public class NonInterceptHorizontalRecyclerView extends RecyclerView { public NonInterceptHorizontalRecyclerView(Context context) { super(context); } public NonInterceptHorizontalRecyclerView(Context context, AttributeSet attrs) { super(context, attrs); } public NonInterceptHorizontalRecyclerView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override public boolean onInterceptTouchEvent(MotionEvent e) { boolean shouldIntercept = super.onInterceptTouchEvent(e); if (shouldIntercept) { // 当RecyclerView决定拦截事件时,阻止父布局拦截 getParent().requestDisallowInterceptTouchEvent(true); } return shouldIntercept; } }
之后在布局文件里直接用这个自定义的RecyclerView代替原生的就行,一次定义到处复用。
这两个方法都能解决你的问题,推荐先用方法一快速验证,要是需要复用就用方法二~
内容的提问来源于stack exchange,提问作者qkjedklajsdfkljsadfklöjsdaklöf
相关产品推荐
相关产品推荐

