Search code examples
androidtouch-eventintercept

Losing ACTION_DOWN parameters when InterceptTouchEvent


I have a parent view which should follow finger on touch and a child view inside it which is clickable. So I used onInterceptTouchEvent to decide if I have to consume the touch event on parent or child by comparing the touch distance before ACTION_UP.

obviously I used "retrun false" on ACTION_DOWN in onInterceptTouchEvent (because it is too early to propagate the event before calculations) So unfortunately the onTouch loses the ACTION_DOWN.

The question is how can I initialize parameters (as well as initial position of parent view) from onTouch (not from onInterceptTouchEvent)?

Footnote: For a reason I have to write onTouch inline with other codes where I have implemented onInterceptTouchEvent inside the object definition.

a part of Object Definition:

boolean mmIsBeingDragged; 
float mLastX;
float mStartX;
int mTouchSlop=ViewConfiguration.get(getContext()).getScaledTouchSlop();

@Override
public boolean onInterceptTouchEvent(MotionEvent event) {

    switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            mLastX = event.getX();
            mStartX = mLastX;
           break;

        case MotionEvent.ACTION_MOVE:
            float x = event.getX();
            float y = event.getY();
            float xDelta = Math.abs(x - mLastX);

            float xDeltaTotal = x - mStartX;
            if (Math.abs(xDeltaTotal) > mTouchSlop) {
                mmIsBeingDragged = true;
                mStartX = x;
                return true;
            }
            break;

        case MotionEvent.ACTION_CANCEL:

        case MotionEvent.ACTION_UP:
            mmIsBeingDragged = false;
            break;
    }
     return false;
}

and this is ontouch which is defined outside of object (inline with program)

    myview.setOnTouchListener(new OnTouchListener() 
    {
        float curX=0;
        float oldX;
        float startX;
        float delta=0;
        float togo;
        boolean mIsBeingDragged=false;
        int mTouchSlop=ViewConfiguration.get(getActivity()).getScaledTouchSlop();

        @Override 
        public boolean onTouch(final View v, MotionEvent event) 
        {
            switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
            //Here is the prblem! How to initialize startX?

            case MotionEvent.ACTION_MOVE:

                curX = event.getRawX();
                delta=curX-startX;
                togo=oldX+delta;

                if (Math.abs(delta) > mTouchSlop) {
                    mIsBeingDragged=true;
                    followfingerFunction(v,togo)
                    return true;
                }
                break;

                case MotionEvent.ACTION_UP:
                    if (!mIsBeingDragged){v.performClick();}
                break;
        }
            return true;
    }
    });

Solution

  • Just expose your mStartX to your activity. ( I know it not perfect but seems OK).

    class ParentView extends ViewGroup (or some other viewGroup) {
        int startX;
        public int getStartX(){
            return startX;
        }
    }
    

    // After that just call getStartX() from your activity.