ACTION_POINTER_DOWN not propagating to sibling view

21 Views Asked by At

In my layout I have a FrameLayout that contains a FrameLayout(buttonContainer) and a Webview(mywebView) over top of each other. The buttonContainer also contains Buttons but for their onTouch event I always return false; so that the buttonContainer handles touch events. (I do this so that I can slide my finger onto the button to activate it.)

The issue I am having is if I have a finger pressed on my buttonContanierand then press a second finger on a location that I know buttonContainer will return false; on, the event does not propagate down to the webview.

MotionEvent.ACTION_POINTER_DOWN and MotionEvent.ACTION_POINTER_UP events are not being passed to my webview even though they are being handled the same way as MotionEvent.ACTION_DOWN and MotionEvent.ACTION_UP which work, I know that the onTouch event returns false for these events.

MotionEvent.ACTION_POINTER_DOWN and MotionEvent.ACTION_POINTER_UP work on my web view only if the are preceded by MotionEvent.ACTION_DOWN and MotionEvent.ACTION_UP events, but as soon as I have an active pointer on the buttonContainer they no longer work until I release that pointer.

Is there a way to allow these events to propagate to my WebView if the are not consumed by buttonContainer?

I have tried explicitly sending the event to my webView mywebView.dispatchTouchEvent(event); when I know the event wont be consumed. The events get sent to my webView but the desired action does not occur, they are just ignored it seems. So I tried modifying the event before it goes to webview setting the action to ACTION_DOWN on pointer 0. This works but then it breaks scrolling on the webview. (I also tried the same modifying the action up event too, same result)

Here is the buttonContainer onTouch:

private void setupButtonTouchListeners() {
        mButtonsContainer.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                boolean buttonActionPerformed = false;
                int action = event.getActionMasked();
                int pointerIndex = event.getActionIndex(); // Index of the pointer that triggered the event
                int pointerId = event.getPointerId(pointerIndex); // Get the pointer ID
                switch (action) {
                    case MotionEvent.ACTION_DOWN:
                    case MotionEvent.ACTION_POINTER_DOWN:
                        // Handle button pressed event
                        for (CustomButton button : mButtons) {
                            if (button.isWithinButtonBounds(event, pointerIndex)) {
                                if (button.setPressed(true, pointerId)) {
                                    buttonActionPerformed = true;
                                }
                            }
                        }
                        break;
                    case MotionEvent.ACTION_MOVE:
                        for (int i = 0; i < event.getPointerCount(); i++) {
                            int currentPointerId = event.getPointerId(i);
                            for (CustomButton button : mButtons) {
                                if (button.isWithinButtonBounds(event, i)) {
                                    if (button.setPressed(true, currentPointerId)) {
                                        buttonActionPerformed = true;
                                    }
                                } else {
                                    if (joystickMode) {
                                        if (button.setPressed(false, currentPointerId)) {
                                            Log.i("APPLOG", "ACTION UP EVENT action preformed");
                                            buttonActionPerformed = true;
                                        }
                                    }
                                }
                            }
                        }
                        break;
                    case MotionEvent.ACTION_UP:
                    case MotionEvent.ACTION_POINTER_UP:
                    case MotionEvent.ACTION_CANCEL:
                        for (CustomButton button : mButtons) {
                            if (button.setPressed(false, pointerId)) {
                                //Log.i("APPLOG", "ACTION UP EVENT action preformed");
                                buttonActionPerformed = true;
                            }
                        }
                        if (!buttonActionPerformed) {
                            Log.i("APPLOG", "Up press no action on pointer: " + event.getPointerId(pointerIndex));
                        }
                        break;
                }

                if (buttonActionPerformed) {
                    //Log.i("APPLOG", "ACTION preformed");
                    return true; // Consume the touch event
                } else {
                    //Log.i("APPLOG", "No action at all");
                    return false; // Let the touch propagate to the WebView
                }
            }
        });
    }

The button.setPressed method just returns whether an action was preformed on a button. Again the buttons are all behaving how I want them to it is only when buttonContainer already has an acvitve pointer that subsequent touch events do not happen on webView.

0

There are 0 best solutions below