将TouchEvent从一个视图转移到另一个视图

时间:2020-09-18 07:30:08

标签: android

我正在使用Android键盘和Popupwindow,在长按键盘键后会打开该窗口。我想将MotionEvent DOWN从键盘直接传输到PopupWindow,这样用户不必执行Action UP或再次Down即可单击popupkeyboard。

这是我在OnLongPress中所做的:

@Override
protected boolean onLongPress(AppKeyboard.Key popupKey) {
        showPopup(popupKey);
        return true;
}

public void showPopup(AppKeyboard.Key popupKey) {
    ContextThemeWrapper ctx = new ContextThemeWrapper(context, R.style.AppTheme);
    LayoutInflater inflater = LayoutInflater.from(ctx);
    View popupView = inflater.inflate(R.layout.popup_layout, null);
    FontsKeyboardView keyboardView = popupView.findViewById(R.id.popup_keyboard_view);
    keyboardView.setClipToOutline(true);
    AppKeyboard keyboard = new AppKeyboard(context, R.xml.popup_test);
    keyboardView.setKeyboard(keyboard);
    popupWindow = new PopupWindow(ctx);
    popupWindow.setContentView(popupView);
    popupWindow.setAttachedInDecor(false);
    popupWindow.setOutsideTouchable(true);
    getLocationInWindow(this.windowOffset);
    int i = this.windowOffset[0] + popupKey.x;
    popupView.measure(MeasureSpec.makeMeasureSpec(getWidth(), MeasureSpec.AT_MOST),
            MeasureSpec.makeMeasureSpec(getHeight(), MeasureSpec.AT_MOST));
    measuredHeight=popupView.getMeasuredHeight();
    int heightoffset= (this.windowOffset[1] + popupKey.y) - measuredHeight;
    Toast.makeText(context, String.valueOf(measuredHeight), Toast.LENGTH_SHORT).show();
    popupWindow.showAtLocation(this, 0, i, heightoffset);

}


@Override
public boolean onTouchEvent(MotionEvent motionEvent) {

    if (this.popupWindow != null) {

        Toast.makeText(context, "Executed", Toast.LENGTH_SHORT).show();
        if (motionEvent.getAction() == MotionEvent.ACTION_POINTER_UP || motionEvent.getAction() == MotionEvent.ACTION_UP) {
            motionEvent = translateToPopupCoordinates(motionEvent, 1);
            motionEvent.recycle();

            PopupWindow popupWindow2 = this.popupWindow;

            this.popupWindow = (PopupWindow) null;

            popupWindow2.dismiss();

            return true;

        } else if (motionEvent.getAction() == MotionEvent.ACTION_MOVE) {

            View contentView = popupWindow.getContentView();

            if (!contentView.isAttachedToWindow()) {
                return true;
            }
            motionEvent = translateToPopupCoordinates(motionEvent, 0);

            popupWindow.getContentView().onTouchEvent(motionEvent);
            motionEvent.recycle();

            return true;
        }
    }
    return super.onTouchEvent(motionEvent);
}

private final MotionEvent translateToPopupCoordinates(MotionEvent motionEvent, int i) {
    long downTime = motionEvent.getDownTime();
    long eventTime = motionEvent.getEventTime();
    float x = ((float) this.windowOffset[0]) + (motionEvent.getX() - ((float) this.windowPopupOffset[0]));
    float y = (motionEvent.getY() - ((float) this.windowPopupOffset[1])) + ((float) this.windowOffset[1]);
    PopupWindow popupWindow = this.popupWindow;
    View contentView = popupWindow.getContentView();
    motionEvent = MotionEvent.obtain(downTime, eventTime, i, x, Math.min(y, ((float) contentView.getHeight()) - ((float) 1)), motionEvent.getMetaState());
    return motionEvent;
}

1 个答案:

答案 0 :(得分:0)

onLongPress返回一个boolean,代表事件是由该方法处理还是应该进一步传播。如果返回true,则基本上是在说“我已经处理了此事件,无需传播”。因此,您实际上可以在此处传递false,然后该事件将传递到队列中的下一个View,以处理该事件。您可能需要对其进行一些微调,以使其适合您的用例。