有没有一种方法只能触发Child的poseDetector?

时间:2019-04-19 03:05:10

标签: java android gesturedetector

我已将“活动”设置为可以检测到左右滑动的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;
        }
    }

1 个答案:

答案 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;
}