首页 > 解决方案 > 将 TouchEvent 从一个视图转移到另一个视图

问题描述

我正在使用 Android 键盘和长按键盘键后打开的弹出窗口。我想将 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;
}

标签: android

解决方案


onLongPress返回 a boolean,它表示事件是由该方法处理还是应该进一步传播。如果你 return true,你基本上是在说“我已经处理了这个事件,不需要传播”。所以你实际上可以通过false那里,然后事件将被传递到View队列中的下一个以处理该事件。您可能需要稍微调整它以使其适用于您的用例。


推荐阅读