View用onClick时Ripple Effect正常,加onTouchListener后失效问题咨询
解决View添加OnTouchListener后涟漪效果失效的问题
哈哈,这个坑我踩过!当你给View设置OnClickListener时涟漪正常,但加了OnTouchListener后涟漪就没了,核心原因是OnTouchListener的返回值会拦截事件传递。
问题根源
Android的触摸事件是按顺序传递的:当你触摸View时,系统先把事件传给OnTouchListener的onTouch()方法。如果这个方法返回true,就表示你已经“消费”了整个触摸事件,系统就不会再把事件往下传递——包括触发OnClickListener的逻辑,以及涟漪效果的触发逻辑!而如果返回false,事件会继续流转,涟漪和点击事件都能正常工作。
针对性解决方案
方案1:不需要消费完整事件时,返回false
如果你的OnTouchListener只是做一些辅助操作(比如监听滑动、记录按下位置),不需要拦截后续事件,直接让onTouch()返回false就行:
yourView.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { // 这里写你的触摸逻辑,比如处理滑动手势 if (event.getAction() == MotionEvent.ACTION_MOVE) { // 执行滑动相关操作 } // 返回false,让事件继续传递,涟漪和OnClick都能正常触发 return false; } });
方案2:必须消费事件时,手动维护涟漪状态
如果你需要拦截触摸事件(比如自己处理点击逻辑),但还想保留涟漪效果,可以手动控制View的按压状态,并在合适时机触发必要的方法:
yourView.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: // 按下时设置View为按压状态,触发涟漪 v.setPressed(true); // 处理你的按下逻辑 return true; case MotionEvent.ACTION_MOVE: // 处理滑动逻辑 return true; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: // 抬起或取消时取消按压状态 v.setPressed(false); // 如果需要触发原有的点击事件,调用performClick() v.performClick(); return false; default: return false; } } });
额外提醒
别忘了确保你的View是可点击的!涟漪效果只有在View的isClickable()返回true时才会生效。如果你的View默认不可点击,可以在XML里加:
android:clickable="true"
或者在代码里设置:
yourView.setClickable(true);
内容的提问来源于stack exchange,提问作者sandeep singh
相关产品推荐
相关产品推荐

