android - 将 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;
}
解决方案
onLongPress
返回 a boolean
,它表示事件是由该方法处理还是应该进一步传播。如果你 return true
,你基本上是在说“我已经处理了这个事件,不需要传播”。所以你实际上可以通过false
那里,然后事件将被传递到View
队列中的下一个以处理该事件。您可能需要稍微调整它以使其适用于您的用例。
推荐阅读
- wso2 - WSO2 EI/ESB:For循环实现
- matlab - 导入工具 - 错误:相同的变量名称 - 列拆分后
- reactjs - 如何确保卸载 React 组件?
- blazor - 强制 blazor 在 javascript 中的浏览器上运行代码
- javascript - RegEx 删除不需要的字符模式
- ffmpeg - ffmpeg 可以同时支持多少个输出
- opc-ua - 问题从 opc ua siemens 服务器 C# 读取 DT(日期和时间)
- sql - 多条件选择
- javascript - 如何根据它们的值连接两个数组
- airflow - Airflow worker 自定义 DAGBag 加载器