我已将“活动”设置为可以检测到左右滑动的gestureDetectorCompat,但是“活动”中还具有水平的RecyclerView。
当我尝试滚动RecyclerView活动时,getsureDetector也会触发,这是不希望的。
如果可以的话,这里是与gestureDetector相关的代码。
private GestureDetectorCompat mDetector;
private static final int SWIPE_MIN_DISTANCE = 120;
private static final int SWIPE_MAX_OFF_PATH = 250;
private static final int SWIPE_THRESHOLD_VELOCITY = 200;
mDetector = new GestureDetectorCompat(this, new SwipeDetector());
public boolean onTouchEvent(MotionEvent event){
this.mDetector.onTouchEvent(event);
return super.onTouchEvent(event);
}
public boolean dispatchTouchEvent(MotionEvent ev){
if (mDetector != null){
if (mDetector.onTouchEvent(ev)){
return true;
}
}
return super.dispatchTouchEvent(ev);
}
public class SwipeDetector extends GestureDetector.SimpleOnGestureListener{
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY){
if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH){
return false;
}
if( e2.getX() > e1.getX() ){
if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY){
Left();
return true;
}
}
if( e1.getX() > e2.getX() ){
if (e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY){
Right();
return true;
}
}
return false;
}
}
答案 0 :(得分:0)
要仅触发RecyclerView
的触摸事件而不将其传递回父母视图,您需要通过在相应的触摸方法中返回true来“消耗”该事件,例如:
recyclerView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
return true; //consume touch event
}
});
还要在父视图(活动)的onTouchEvent()
中删除对dispatchTouchEvent
的调用,以使其在将触摸事件传播到其子视图之前不会触发触摸事件(在RecyclerView
)并消耗掉。
或者,您可以通过在RecyclerView的项目触摸侦听器中覆盖RecyclerView
来拦截传递给onInterceptTouchEvent
的所有触摸事件并自己处理(就像有条件地使用它们)。当您还必须处理RecyclerView
内部的子视图并且希望有条件地让子视图获取(或调度)触摸事件时,这很有用。一个例子就是这样:
recyclerView.addOnItemTouchListener(new RecyclerView.OnItemTouchListener(){
@Override
public boolean onInterceptTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e) {
return true;
}
@Override
public void onTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e) {
}
@Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}
});
您还可以通过检查传入的触摸事件/ recyclerview
状态的操作,并返回true进行消费,或者返回false传递给其他父视图,来更好地控制何时拦截事件以及何时不拦截事件。例如:
@Override
public boolean onInterceptTouchEvent(@NonNull RecyclerView rv, @NonNull MotionEvent e) {
if (e.getAction() == MotionEvent.ACTION_DOWN && rv.getScrollState() == RecyclerView.SCROLL_STATE_DRAGGING) {
Log.d(TAG, "onInterceptTouchEvent: click performed");
rv.findChildViewUnder(e.getX(), e.getY()).performClick();
return true;
}
return false;
}