Search code examples
androiduser-interfaceontouchlisteneronlongclicklistener

OnLongClickListener on childView disables OnTouchListener on parentView


I have an AbsoluteLayout which has an OnTouchListener. Inside this layout there is a much smaller LinearLayout positioned dynamically. The OnTouchListener works as expected.

Now the problem comes when I add a LongClickListener to my LinearLayout. That disables my OnTouchListener if the touch hits the LinearLayout, but it is still triggered if the LinearLayout was not hit by the touch.

My listeners:

// listener on parent (AbsoluteLayout)
setOnTouchListener(new OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        Log.e("LOOOOGING");
        mLinearLayout.getHitRect(mNoteRect);
        mNoteRect.left += mX;
        mNoteRect.top += mY;
        mNoteRect.right = mNoteRect.left + mLinearLayout.getWidth();
        mNoteRect.bottom = mNoteRect.top + mLinearLayout.getHeight();
        if (mNoteRect.contains((int) event.getX(), (int) event.getY())) {
            if (event.getAction() == MotionEvent.ACTION_DOWN) {
                mStartX = (int) event.getX() - mNoteRect.left;
                mStartY = (int) event.getY() - mNoteRect.top;
                return true;
            }
            mX = (int) event.getX() - mStartX;
            mY = (int) event.getY() - mStartY;

            setPadding(mX, mY, 0, 0);
            return true;
        }
        return false;
    }
});

// listener on child (LinearLayout)
mLinearLayout.setOnLongClickListener(new OnLongClickListener() {
    @Override
    public boolean onLongClick(View v) {
        // do something...
        return true;
    }
});

How can I delegate the touch on the LinearLayout where the OnLongClickListener is registered, to the parent?


Solution

  • I had to build my own longclick behavior inside my ontouchlistener

    private Handler mLongPressHandler = new Handler();
    
    public final Runnable mDoLongPress = new Runnable() {
        public void run() {
            // do something
        }
    };
    
    setOnTouchListener(new OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            mLinearLayout.getHitRect(mNoteRect);
            mNoteRect.left += mX;
            mNoteRect.top += mY;
            mNoteRect.right = mNoteRect.left + mLinearLayout.getWidth();
            mNoteRect.bottom = mNoteRect.top + mLinearLayout.getHeight();
            if (mNoteRect.contains((int) event.getX(), (int) event.getY())) {
                if (event.getAction() == MotionEvent.ACTION_DOWN) {
                    mStartRawX = (int) event.getX();
                    mStartRawY = (int) event.getY();
                    mStartX = mStartRawX - mNoteRect.left;
                    mStartY = mStartRawY - mNoteRect.top;
                    mLongPressHandler.postDelayed(mDoLongPress, 1000);
                    return true;
                }
                mX = (int) event.getX() - mStartX;
                mY = (int) event.getY() - mStartY;
                if (event.getAction() == MotionEvent.ACTION_MOVE) {
                    if ((mStartRawX + 10 < (int) event.getX() || mStartRawX - 10 > (int) event.getX())
                            || (mStartRawY + 10 < (int) event.getY() || mStartRawY - 10 > (int) event.getY())) {
                        mLongPressHandler.removeCallbacks(mDoLongPress);
                    }
                }
                if (event.getAction() == MotionEvent.ACTION_UP) {
                    mLongPressHandler.removeCallbacks(mDoLongPress);
                }
    
                setPadding(mX, mY, 0, 0);
                return true;
            }
            return false;
        }
    });