处理触摸事件 - onInterceptTouchEvent和onTouchEvent

时间:2014-12-10 16:28:54

标签: android onclick touch ontouchevent

我希望能够在屏幕上的任何位置滑动以调用某个功能。但我希望Buttons中的Linear Layouts能够点击。如果我按Button我想要onInterceptTouchEvent InterceptButton onTouchEvent Button,请执行滑动操作。如果我只是点击onInterceptTouchEvent,我就不希望调用Button。相反,我希望调用onTouchEvent的{​​{1}}并执行Button click

但是当我尝试实施onInterceptTouchEvent时,我遇到了错误。

这是我的代码:

public class Game extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.game_activity);

   //other code....
}
}

@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
    switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            break;
        case MotionEvent.ACTION_CANCEL:
        case MotionEvent.ACTION_UP:
            swipeScreen(); //if action recognized as swipe then swipe
            break;
        case MotionEvent.ACTION_MOVE:
            float x = event.getX();
            float y = event.getY();
            float xDelta = Math.abs(x - mLastX);
            float yDelta = Math.abs(y - mLastY);

            if (yDelta > xDelta) {
                return true;
            }
            break;
    }

    return false;
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    ButtonOnClick(); //if not a swipe, then button click
    return true;
}

首先出现错误:The method onInterceptTouchEvent(MotionEvent) of type Game must override or implement a supertype method

然后我将代码更改为return true而不是return super.onInterceptTouchEvent(event),但我收到错误消息:The method onInterceptTouchEvent(MotionEvent) is undefined for the type Activity

有人可以帮忙吗?

2 个答案:

答案 0 :(得分:12)

请注意,onInterceptTouchEvent()是来自ViewGroup类的方法,而不是来自Activity的方法。

您可以将逻辑从onInterceptTouchEvent()移至dispatchTouchEvent(MotionEvent ev),从而实现所需的行为。请记住调用dispatchTouchEvent(MotionEvent ev)的超类实现来处理应该正常处理的事件。

另请注意,只有当delta大于system constant for touch slop时,才应将移动视为滑动。我建议您通过测试yDelta / 2 > xDelta而不是yDelta > xDelta来确保用户正朝着您想要的方向滑动。

public class Game extends Activity {
    private int mSlop;
    private float mDownX;
    private float mDownY;
    private boolean mSwiping;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.game_activity);

        ViewConfiguration vc = ViewConfiguration.get(this)
        mSlop = vc.getScaledTouchSlop();

       //other code....
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                mDownX = ev.getX();
                mDownY = ev.getY();
                mSwiping = false;
                break;
            case MotionEvent.ACTION_CANCEL:
            case MotionEvent.ACTION_UP:
                if(mSwiping) {
                    swipeScreen(); //if action recognized as swipe then swipe
                }
                break;
            case MotionEvent.ACTION_MOVE:
                float x = ev.getX();
                float y = ev.getY();
                float xDelta = Math.abs(x - mDownX);
                float yDelta = Math.abs(y - mDownY);

                if (yDelta > mSlop && yDelta / 2 > xDelta) {
                    mSwiping = true;
                    return true;
                }
                break;
        }

        return super.dispatchTouchEvent(ev);
    }
}

答案 1 :(得分:0)

我使用fernandohur方法(请阅读他的post),该方法非常可重用,自成体系,并提供了检测任意方向上的滑动所需的一切。

要使用fernandohur onSwipeListener,请遵循以下简单步骤。所有代码都是用Kotlin编写的:

// 1) Add his onSwipeListener to the project. Credits should go to him

// 2) Implement an anonymous class for the swipe listener:
val onSwipeListener: OnSwipeListener = object : OnSwipeListener() {
    override fun onSwipe(direction: Direction): Boolean {

        if (direction == Direction.Up) {
            //do somethin
            return true
        } else if (direction == Direction.Down) {
            //do something else
            return true
        }
        return super.onSwipe(direction)
    }
}

// 3) connect the listener to the view
val mDetector = GestureDetectorCompat(this.context, onSwipeListener)

// 4) route the touch events to the listener
override fun onInterceptTouchEvent(event: MotionEvent?): Boolean {
    return if (this.mDetector!!.onTouchEvent(event)) {
        true
    } else super.onInterceptTouchEvent(event)
}