Gluon Mobile 中的 JavaFX TextField 重点 属性 问题
JavaFX TextField Focused Property Issue in Gluon Mobile
在将应用程序移植到移动设备时(在 iOS 上),我认为有几件事情正在发生。
- 当我通过触摸 TextField 开始滚动时,文本字段聚焦然后在滚动过程中固定在屏幕上。
- 我在该字段上进行了一些验证,以便当该字段失去焦点时,会弹出一个指定错误的模式。但是,在 iPhone 中,文本字段保持聚焦并显示在对话框上方。
请注意,我使用的是 JavaFX 本机触摸字段而不是 Gluon 版本,因为我在使用 Gluon 版本的 TextField 的 focusedProperty 时遇到了问题。它的工作方式是,如果输入无效,它会将字段的值设置为空字符串并打开对话框。
我尝试了以下方法:
- 在显示模式之前,requestFocus 在视图上。
- 在滚动窗格滚动时,将 requestFocus 放在滚动窗格上(滚动窗格有自己的自定义外观,我可以在它滚动时在其上添加 requestFocus)。
JavaFX TextField
和 Gluon 都会出现您面临的问题,因为后者在内部使用内置的 JavaFX 控件。
iOS问题的原因是这样的:当JavaFXTextField
获得焦点时,在控件顶部添加了一个原生的iOSUITextField
, 基本上是为了启用与本机软件键盘的交互。
您可以看到 TextFieldBehavior
在 iOS 上有一个 specific call:
private void handleFocusChange() {
TextField textField = getControl();
if (textField.isFocused()) {
if (PlatformUtil.isIOS()) {
...
textField.getScene().getWindow().impl_getPeer().requestInput(text, type.ordinal(), w, h,
trans.getMxx(), trans.getMxy(), trans.getMxz(), trans.getMxt(),// + insets.getLeft(),
trans.getMyx(), trans.getMyy(), trans.getMyz(), trans.getMyt(),// + insets.getTop(),
trans.getMzx(), trans.getMzy(), trans.getMzz(), trans.getMzt(), textField.getFont().getSize());
...
}
}
}
直接转到本机 implementation:
UITextField* textField = [[UITextField alloc] initWithFrame:CGRectMake(mxt + 1, myt + 1, mxx * (width - 2), myy * (height - 2))];
到目前为止,只要您不在本机 UITextField
可见时滚动和移动 JavaFX TextField
初始位置,它就可以正常工作。
另请注意,带有本机控件的 iOS 层位于 JavaFX 层之上(这就是为什么您一直在对话框顶部看到本机编辑器的原因)。
有一个开放的 PR 支持在软件键盘出现时更新本机控件位置,翻译 JavaFX 和 iOS 控件,并引入 updateBounds
method ,可以在滚动事件移动 TextField
.
的情况下使用
与此同时,您必须添加一些解决方法来防止在 TextField
聚焦时滚动。
在将应用程序移植到移动设备时(在 iOS 上),我认为有几件事情正在发生。
- 当我通过触摸 TextField 开始滚动时,文本字段聚焦然后在滚动过程中固定在屏幕上。
- 我在该字段上进行了一些验证,以便当该字段失去焦点时,会弹出一个指定错误的模式。但是,在 iPhone 中,文本字段保持聚焦并显示在对话框上方。
请注意,我使用的是 JavaFX 本机触摸字段而不是 Gluon 版本,因为我在使用 Gluon 版本的 TextField 的 focusedProperty 时遇到了问题。它的工作方式是,如果输入无效,它会将字段的值设置为空字符串并打开对话框。
我尝试了以下方法:
- 在显示模式之前,requestFocus 在视图上。
- 在滚动窗格滚动时,将 requestFocus 放在滚动窗格上(滚动窗格有自己的自定义外观,我可以在它滚动时在其上添加 requestFocus)。
JavaFX TextField
和 Gluon 都会出现您面临的问题,因为后者在内部使用内置的 JavaFX 控件。
iOS问题的原因是这样的:当JavaFXTextField
获得焦点时,在控件顶部添加了一个原生的iOSUITextField
, 基本上是为了启用与本机软件键盘的交互。
您可以看到 TextFieldBehavior
在 iOS 上有一个 specific call:
private void handleFocusChange() {
TextField textField = getControl();
if (textField.isFocused()) {
if (PlatformUtil.isIOS()) {
...
textField.getScene().getWindow().impl_getPeer().requestInput(text, type.ordinal(), w, h,
trans.getMxx(), trans.getMxy(), trans.getMxz(), trans.getMxt(),// + insets.getLeft(),
trans.getMyx(), trans.getMyy(), trans.getMyz(), trans.getMyt(),// + insets.getTop(),
trans.getMzx(), trans.getMzy(), trans.getMzz(), trans.getMzt(), textField.getFont().getSize());
...
}
}
}
直接转到本机 implementation:
UITextField* textField = [[UITextField alloc] initWithFrame:CGRectMake(mxt + 1, myt + 1, mxx * (width - 2), myy * (height - 2))];
到目前为止,只要您不在本机 UITextField
可见时滚动和移动 JavaFX TextField
初始位置,它就可以正常工作。
另请注意,带有本机控件的 iOS 层位于 JavaFX 层之上(这就是为什么您一直在对话框顶部看到本机编辑器的原因)。
有一个开放的 PR 支持在软件键盘出现时更新本机控件位置,翻译 JavaFX 和 iOS 控件,并引入 updateBounds
method ,可以在滚动事件移动 TextField
.
与此同时,您必须添加一些解决方法来防止在 TextField
聚焦时滚动。